From 9c767be2b9c29579a78a84ffbbbba22bddd883eb Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Thu, 24 Oct 2024 02:13:24 +0000 Subject: [PATCH 1/3] chore: Configure Ruby clients for google-ads-ad_manager PiperOrigin-RevId: 689139590 Source-Link: https://github.com/googleapis/googleapis/commit/296f2ac1aa9abccb7708b639b7839faa1809087f Source-Link: https://github.com/googleapis/googleapis-gen/commit/26927362e0aa1293258fc23fe3ce83c5c21d5fbb Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLXNob3BwaW5nLW1lcmNoYW50LXByb21vdGlvbnMvLk93bEJvdC55YW1sIiwiaCI6IjI2OTI3MzYyZTBhYTEyOTMyNThmYzIzZmUzY2U4M2M1YzIxZDVmYmIifQ== Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLXNob3BwaW5nLW1lcmNoYW50LXF1b3RhLy5Pd2xCb3QueWFtbCIsImgiOiIyNjkyNzM2MmUwYWExMjkzMjU4ZmMyM2ZlM2NlODNjNWMyMWQ1ZmJiIn0= Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLXNob3BwaW5nLW1lcmNoYW50LXJlcG9ydHMvLk93bEJvdC55YW1sIiwiaCI6IjI2OTI3MzYyZTBhYTEyOTMyNThmYzIzZmUzY2U4M2M1YzIxZDVmYmIifQ== Copy-Tag: eyJwIjoicGFja2FnZXMvZ29vZ2xlLXNob3BwaW5nLXR5cGUvLk93bEJvdC55YW1sIiwiaCI6IjI2OTI3MzYyZTBhYTEyOTMyNThmYzIzZmUzY2U4M2M1YzIxZDVmYmIifQ== Copy-Tag: eyJwIjoicGFja2FnZXMvZ3JhZmVhcy8uT3dsQm90LnlhbWwiLCJoIjoiMjY5MjczNjJlMGFhMTI5MzI1OGZjMjNmZTNjZTgzYzVjMjFkNWZiYiJ9 --- .../v1beta/.coveragerc | 13 + .../v1beta/.flake8 | 33 + .../v1beta/MANIFEST.in | 2 + .../v1beta/README.rst | 49 + .../v1beta/docs/_static/custom.css | 3 + .../v1beta/docs/conf.py | 376 + .../v1beta/docs/index.rst | 7 + .../promotions_service.rst | 10 + .../merchant_promotions_v1beta/services_.rst | 6 + .../merchant_promotions_v1beta/types_.rst | 6 + .../shopping/merchant_promotions/__init__.py | 51 + .../merchant_promotions/gapic_version.py | 16 + .../shopping/merchant_promotions/py.typed | 2 + .../merchant_promotions_v1beta/__init__.py | 52 + .../gapic_metadata.json | 73 + .../gapic_version.py | 16 + .../merchant_promotions_v1beta/py.typed | 2 + .../services/__init__.py | 15 + .../services/promotions_service/__init__.py | 22 + .../promotions_service/async_client.py | 584 + .../services/promotions_service/client.py | 939 ++ .../services/promotions_service/pagers.py | 162 + .../promotions_service/transports/README.rst | 9 + .../promotions_service/transports/__init__.py | 38 + .../promotions_service/transports/base.py | 182 + .../promotions_service/transports/grpc.py | 334 + .../transports/grpc_asyncio.py | 365 + .../promotions_service/transports/rest.py | 511 + .../transports/rest_base.py | 212 + .../types/__init__.py | 46 + .../types/promotions.py | 277 + .../types/promotions_common.py | 671 + .../v1beta/mypy.ini | 3 + .../v1beta/noxfile.py | 280 + ..._promotions_service_get_promotion_async.py | 52 + ...d_promotions_service_get_promotion_sync.py | 52 + ...omotions_service_insert_promotion_async.py | 60 + ...romotions_service_insert_promotion_sync.py | 60 + ...romotions_service_list_promotions_async.py | 53 + ...promotions_service_list_promotions_sync.py | 53 + ...e.shopping.merchant.promotions.v1beta.json | 490 + ...xup_merchant_promotions_v1beta_keywords.py | 178 + .../v1beta/setup.py | 99 + .../v1beta/testing/constraints-3.10.txt | 7 + .../v1beta/testing/constraints-3.11.txt | 7 + .../v1beta/testing/constraints-3.12.txt | 7 + .../v1beta/testing/constraints-3.13.txt | 7 + .../v1beta/testing/constraints-3.7.txt | 11 + .../v1beta/testing/constraints-3.8.txt | 7 + .../v1beta/testing/constraints-3.9.txt | 7 + .../v1beta/tests/__init__.py | 16 + .../v1beta/tests/unit/__init__.py | 16 + .../v1beta/tests/unit/gapic/__init__.py | 16 + .../merchant_promotions_v1beta/__init__.py | 16 + .../test_promotions_service.py | 3661 +++++ .../v1beta/.coveragerc | 13 + .../v1beta/.flake8 | 33 + .../v1beta/MANIFEST.in | 2 + .../v1beta/README.rst | 49 + .../v1beta/docs/_static/custom.css | 3 + .../v1beta/docs/conf.py | 376 + .../v1beta/docs/index.rst | 7 + .../merchant_quota_v1beta/quota_service.rst | 10 + .../docs/merchant_quota_v1beta/services_.rst | 6 + .../docs/merchant_quota_v1beta/types_.rst | 6 + .../shopping/merchant_quota/__init__.py | 35 + .../shopping/merchant_quota/gapic_version.py | 16 + .../google/shopping/merchant_quota/py.typed | 2 + .../merchant_quota_v1beta/__init__.py | 36 + .../merchant_quota_v1beta/gapic_metadata.json | 43 + .../merchant_quota_v1beta/gapic_version.py | 16 + .../shopping/merchant_quota_v1beta/py.typed | 2 + .../services/__init__.py | 15 + .../services/quota_service/__init__.py | 22 + .../services/quota_service/async_client.py | 360 + .../services/quota_service/client.py | 716 + .../services/quota_service/pagers.py | 162 + .../quota_service/transports/README.rst | 9 + .../quota_service/transports/__init__.py | 38 + .../services/quota_service/transports/base.py | 154 + .../services/quota_service/transports/grpc.py | 272 + .../quota_service/transports/grpc_asyncio.py | 293 + .../services/quota_service/transports/rest.py | 276 + .../quota_service/transports/rest_base.py | 128 + .../merchant_quota_v1beta/types/__init__.py | 28 + .../merchant_quota_v1beta/types/quota.py | 184 + .../v1beta/mypy.ini | 3 + .../v1beta/noxfile.py | 280 + ...d_quota_service_list_quota_groups_async.py | 53 + ...ed_quota_service_list_quota_groups_sync.py | 53 + ...google.shopping.merchant.quota.v1beta.json | 176 + .../fixup_merchant_quota_v1beta_keywords.py | 176 + .../v1beta/setup.py | 98 + .../v1beta/testing/constraints-3.10.txt | 6 + .../v1beta/testing/constraints-3.11.txt | 6 + .../v1beta/testing/constraints-3.12.txt | 6 + .../v1beta/testing/constraints-3.13.txt | 6 + .../v1beta/testing/constraints-3.7.txt | 10 + .../v1beta/testing/constraints-3.8.txt | 6 + .../v1beta/testing/constraints-3.9.txt | 6 + .../v1beta/tests/__init__.py | 16 + .../v1beta/tests/unit/__init__.py | 16 + .../v1beta/tests/unit/gapic/__init__.py | 16 + .../gapic/merchant_quota_v1beta/__init__.py | 16 + .../test_quota_service.py | 2403 ++++ .../v1beta/.coveragerc | 13 + .../v1beta/.flake8 | 33 + .../v1beta/MANIFEST.in | 2 + .../v1beta/README.rst | 49 + .../v1beta/docs/_static/custom.css | 3 + .../v1beta/docs/conf.py | 376 + .../v1beta/docs/index.rst | 7 + .../report_service.rst | 10 + .../merchant_reports_v1beta/services_.rst | 6 + .../docs/merchant_reports_v1beta/types_.rst | 6 + .../shopping/merchant_reports/__init__.py | 63 + .../merchant_reports/gapic_version.py | 16 + .../google/shopping/merchant_reports/py.typed | 2 + .../merchant_reports_v1beta/__init__.py | 64 + .../gapic_metadata.json | 43 + .../merchant_reports_v1beta/gapic_version.py | 16 + .../shopping/merchant_reports_v1beta/py.typed | 2 + .../services/__init__.py | 15 + .../services/report_service/__init__.py | 22 + .../services/report_service/async_client.py | 361 + .../services/report_service/client.py | 708 + .../services/report_service/pagers.py | 162 + .../report_service/transports/README.rst | 9 + .../report_service/transports/__init__.py | 38 + .../report_service/transports/base.py | 154 + .../report_service/transports/grpc.py | 275 + .../report_service/transports/grpc_asyncio.py | 296 + .../report_service/transports/rest.py | 279 + .../report_service/transports/rest_base.py | 138 + .../merchant_reports_v1beta/types/__init__.py | 56 + .../merchant_reports_v1beta/types/reports.py | 2521 ++++ .../v1beta/mypy.ini | 3 + .../v1beta/noxfile.py | 280 + ...a_generated_report_service_search_async.py | 54 + ...ta_generated_report_service_search_sync.py | 54 + ...ogle.shopping.merchant.reports.v1beta.json | 176 + .../fixup_merchant_reports_v1beta_keywords.py | 176 + .../v1beta/setup.py | 99 + .../v1beta/testing/constraints-3.10.txt | 7 + .../v1beta/testing/constraints-3.11.txt | 7 + .../v1beta/testing/constraints-3.12.txt | 7 + .../v1beta/testing/constraints-3.13.txt | 7 + .../v1beta/testing/constraints-3.7.txt | 11 + .../v1beta/testing/constraints-3.8.txt | 7 + .../v1beta/testing/constraints-3.9.txt | 7 + .../v1beta/tests/__init__.py | 16 + .../v1beta/tests/unit/__init__.py | 16 + .../v1beta/tests/unit/gapic/__init__.py | 16 + .../gapic/merchant_reports_v1beta/__init__.py | 16 + .../test_report_service.py | 2389 +++ .../google-shopping-type-py/.coveragerc | 13 + .../google-shopping-type-py/.flake8 | 33 + .../google-shopping-type-py/MANIFEST.in | 2 + .../google-shopping-type-py/README.rst | 49 + .../docs/_static/custom.css | 3 + .../google-shopping-type-py/docs/conf.py | 376 + .../google-shopping-type-py/docs/index.rst | 7 + .../docs/type/services_.rst | 4 + .../docs/type/types_.rst | 6 + .../google/shopping/type/__init__.py | 36 + .../google/shopping/type/gapic_metadata.json | 7 + .../google/shopping/type/gapic_version.py | 16 + .../google/shopping/type/py.typed | 2 + .../google/shopping/type/services/__init__.py | 15 + .../google/shopping/type/types/__init__.py | 32 + .../google/shopping/type/types/types.py | 297 + .../google-shopping-type-py/mypy.ini | 3 + .../google-shopping-type-py/noxfile.py | 280 + .../scripts/fixup_type_keywords.py | 175 + .../google-shopping-type-py/setup.py | 98 + .../testing/constraints-3.10.txt | 6 + .../testing/constraints-3.11.txt | 6 + .../testing/constraints-3.12.txt | 6 + .../testing/constraints-3.13.txt | 6 + .../testing/constraints-3.7.txt | 10 + .../testing/constraints-3.8.txt | 6 + .../testing/constraints-3.9.txt | 6 + .../google-shopping-type-py/tests/__init__.py | 16 + .../tests/unit/__init__.py | 16 + .../tests/unit/gapic/__init__.py | 16 + .../tests/unit/gapic/type/__init__.py | 16 + owl-bot-staging/grafeas/v1/.coveragerc | 13 + owl-bot-staging/grafeas/v1/.flake8 | 33 + owl-bot-staging/grafeas/v1/MANIFEST.in | 2 + owl-bot-staging/grafeas/v1/README.rst | 49 + .../grafeas/v1/docs/_static/custom.css | 3 + owl-bot-staging/grafeas/v1/docs/conf.py | 376 + .../grafeas/v1/docs/grafeas_v1/grafeas.rst | 10 + .../grafeas/v1/docs/grafeas_v1/services_.rst | 6 + .../grafeas/v1/docs/grafeas_v1/types_.rst | 6 + owl-bot-staging/grafeas/v1/docs/index.rst | 7 + .../grafeas/v1/grafeas/grafeas/__init__.py | 211 + .../v1/grafeas/grafeas/gapic_version.py | 16 + .../grafeas/v1/grafeas/grafeas/py.typed | 2 + .../grafeas/v1/grafeas/grafeas_v1/__init__.py | 212 + .../v1/grafeas/grafeas_v1/gapic_metadata.json | 238 + .../v1/grafeas/grafeas_v1/gapic_version.py | 16 + .../grafeas/v1/grafeas/grafeas_v1/py.typed | 2 + .../grafeas/grafeas_v1/services/__init__.py | 15 + .../grafeas_v1/services/grafeas/__init__.py | 22 + .../services/grafeas/async_client.py | 1836 +++ .../grafeas_v1/services/grafeas/client.py | 2196 +++ .../grafeas_v1/services/grafeas/pagers.py | 432 + .../services/grafeas/transports/README.rst | 9 + .../services/grafeas/transports/__init__.py | 38 + .../services/grafeas/transports/base.py | 416 + .../services/grafeas/transports/grpc.py | 631 + .../grafeas/transports/grpc_asyncio.py | 797 + .../services/grafeas/transports/rest.py | 1629 +++ .../services/grafeas/transports/rest_base.py | 732 + .../v1/grafeas/grafeas_v1/types/__init__.py | 244 + .../grafeas/grafeas_v1/types/attestation.py | 148 + .../v1/grafeas/grafeas_v1/types/build.py | 115 + .../v1/grafeas/grafeas_v1/types/common.py | 295 + .../v1/grafeas/grafeas_v1/types/compliance.py | 215 + .../v1/grafeas/grafeas_v1/types/cvss.py | 464 + .../v1/grafeas/grafeas_v1/types/deployment.py | 125 + .../v1/grafeas/grafeas_v1/types/discovery.py | 281 + .../grafeas_v1/types/dsse_attestation.py | 102 + .../v1/grafeas/grafeas_v1/types/grafeas.py | 921 ++ .../v1/grafeas/grafeas_v1/types/image.py | 158 + .../grafeas_v1/types/intoto_provenance.py | 248 + .../grafeas_v1/types/intoto_statement.py | 353 + .../v1/grafeas/grafeas_v1/types/package.py | 378 + .../v1/grafeas/grafeas_v1/types/provenance.py | 597 + .../v1/grafeas/grafeas_v1/types/sbom.py | 171 + .../v1/grafeas/grafeas_v1/types/severity.py | 56 + .../grafeas_v1/types/slsa_provenance.py | 258 + .../types/slsa_provenance_zero_two.py | 242 + .../v1/grafeas/grafeas_v1/types/upgrade.py | 266 + .../v1/grafeas/grafeas_v1/types/vex.py | 384 + .../grafeas/grafeas_v1/types/vulnerability.py | 594 + owl-bot-staging/grafeas/v1/mypy.ini | 3 + owl-bot-staging/grafeas/v1/noxfile.py | 280 + ...erated_grafeas_batch_create_notes_async.py | 52 + ...nerated_grafeas_batch_create_notes_sync.py | 52 + ..._grafeas_batch_create_occurrences_async.py | 52 + ...d_grafeas_batch_create_occurrences_sync.py | 52 + ..._v1_generated_grafeas_create_note_async.py | 53 + ...s_v1_generated_grafeas_create_note_sync.py | 53 + ...nerated_grafeas_create_occurrence_async.py | 52 + ...enerated_grafeas_create_occurrence_sync.py | 52 + ..._v1_generated_grafeas_delete_note_async.py | 50 + ...s_v1_generated_grafeas_delete_note_sync.py | 50 + ...nerated_grafeas_delete_occurrence_async.py | 50 + ...enerated_grafeas_delete_occurrence_sync.py | 50 + ...sis_v1_generated_grafeas_get_note_async.py | 52 + ...ysis_v1_generated_grafeas_get_note_sync.py | 52 + ..._generated_grafeas_get_occurrence_async.py | 52 + ...rated_grafeas_get_occurrence_note_async.py | 52 + ...erated_grafeas_get_occurrence_note_sync.py | 52 + ...1_generated_grafeas_get_occurrence_sync.py | 52 + ...ted_grafeas_list_note_occurrences_async.py | 53 + ...ated_grafeas_list_note_occurrences_sync.py | 53 + ...s_v1_generated_grafeas_list_notes_async.py | 53 + ...is_v1_generated_grafeas_list_notes_sync.py | 53 + ...enerated_grafeas_list_occurrences_async.py | 53 + ...generated_grafeas_list_occurrences_sync.py | 53 + ..._v1_generated_grafeas_update_note_async.py | 52 + ...s_v1_generated_grafeas_update_note_sync.py | 52 + ...nerated_grafeas_update_occurrence_async.py | 52 + ...enerated_grafeas_update_occurrence_sync.py | 52 + .../snippet_metadata_grafeas.v1.json | 2353 +++ .../v1/scripts/fixup_grafeas_v1_keywords.py | 189 + owl-bot-staging/grafeas/v1/setup.py | 98 + .../grafeas/v1/testing/constraints-3.10.txt | 6 + .../grafeas/v1/testing/constraints-3.11.txt | 6 + .../grafeas/v1/testing/constraints-3.12.txt | 6 + .../grafeas/v1/testing/constraints-3.13.txt | 6 + .../grafeas/v1/testing/constraints-3.7.txt | 10 + .../grafeas/v1/testing/constraints-3.8.txt | 6 + .../grafeas/v1/testing/constraints-3.9.txt | 6 + owl-bot-staging/grafeas/v1/tests/__init__.py | 16 + .../grafeas/v1/tests/unit/__init__.py | 16 + .../grafeas/v1/tests/unit/gapic/__init__.py | 16 + .../tests/unit/gapic/grafeas_v1/__init__.py | 16 + .../unit/gapic/grafeas_v1/test_grafeas.py | 11984 ++++++++++++++++ 282 files changed, 60606 insertions(+) create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/.coveragerc create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/.flake8 create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/MANIFEST.in create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/README.rst create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/_static/custom.css create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/conf.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/index.rst create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/promotions_service.rst create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/services_.rst create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/types_.rst create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/gapic_version.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/py.typed create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_metadata.json create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_version.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/py.typed create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/async_client.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/client.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/pagers.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/README.rst create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/base.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest_base.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions_common.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/mypy.ini create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/noxfile.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_async.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_sync.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_async.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_sync.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_async.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_sync.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1beta.json create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/scripts/fixup_merchant_promotions_v1beta_keywords.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/setup.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.10.txt create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.11.txt create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.12.txt create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.13.txt create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.7.txt create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.8.txt create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.9.txt create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/.coveragerc create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/.flake8 create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/MANIFEST.in create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/README.rst create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/_static/custom.css create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/conf.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/index.rst create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/quota_service.rst create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/services_.rst create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/types_.rst create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/gapic_version.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/py.typed create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_metadata.json create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_version.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/py.typed create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/async_client.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/client.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/pagers.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/README.rst create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/base.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest_base.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/quota.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/mypy.ini create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/noxfile.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_async.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_sync.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1beta.json create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/scripts/fixup_merchant_quota_v1beta_keywords.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/setup.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.10.txt create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.11.txt create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.12.txt create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.13.txt create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.7.txt create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.8.txt create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.9.txt create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/.coveragerc create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/.flake8 create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/MANIFEST.in create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/README.rst create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/_static/custom.css create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/conf.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/index.rst create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/report_service.rst create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/services_.rst create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/types_.rst create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/gapic_version.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/py.typed create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_metadata.json create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_version.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/py.typed create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/async_client.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/client.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/pagers.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/README.rst create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/base.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest_base.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/reports.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/mypy.ini create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/noxfile.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_async.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_sync.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1beta.json create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/scripts/fixup_merchant_reports_v1beta_keywords.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/setup.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.10.txt create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.11.txt create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.12.txt create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.13.txt create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.7.txt create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.8.txt create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.9.txt create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/__init__.py create mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/.coveragerc create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/.flake8 create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/MANIFEST.in create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/README.rst create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/_static/custom.css create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/conf.py create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/index.rst create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/services_.rst create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/types_.rst create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/__init__.py create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_metadata.json create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_version.py create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/py.typed create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/services/__init__.py create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/__init__.py create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/types.py create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/mypy.ini create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/noxfile.py create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/scripts/fixup_type_keywords.py create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/setup.py create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.10.txt create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.11.txt create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.12.txt create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.13.txt create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.7.txt create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.8.txt create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.9.txt create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/__init__.py create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/__init__.py create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/gapic/type/__init__.py create mode 100644 owl-bot-staging/grafeas/v1/.coveragerc create mode 100644 owl-bot-staging/grafeas/v1/.flake8 create mode 100644 owl-bot-staging/grafeas/v1/MANIFEST.in create mode 100644 owl-bot-staging/grafeas/v1/README.rst create mode 100644 owl-bot-staging/grafeas/v1/docs/_static/custom.css create mode 100644 owl-bot-staging/grafeas/v1/docs/conf.py create mode 100644 owl-bot-staging/grafeas/v1/docs/grafeas_v1/grafeas.rst create mode 100644 owl-bot-staging/grafeas/v1/docs/grafeas_v1/services_.rst create mode 100644 owl-bot-staging/grafeas/v1/docs/grafeas_v1/types_.rst create mode 100644 owl-bot-staging/grafeas/v1/docs/index.rst create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas/__init__.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas/gapic_version.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas/py.typed create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/__init__.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_metadata.json create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_version.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/py.typed create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/__init__.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/__init__.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/async_client.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/client.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/pagers.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/README.rst create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/__init__.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/base.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest_base.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/__init__.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/attestation.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/build.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/common.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/compliance.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/cvss.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/deployment.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/discovery.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/dsse_attestation.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/grafeas.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/image.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_provenance.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_statement.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/package.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/provenance.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/sbom.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/severity.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance_zero_two.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/upgrade.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vex.py create mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vulnerability.py create mode 100644 owl-bot-staging/grafeas/v1/mypy.ini create mode 100644 owl-bot-staging/grafeas/v1/noxfile.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_async.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_sync.py create mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/snippet_metadata_grafeas.v1.json create mode 100644 owl-bot-staging/grafeas/v1/scripts/fixup_grafeas_v1_keywords.py create mode 100644 owl-bot-staging/grafeas/v1/setup.py create mode 100644 owl-bot-staging/grafeas/v1/testing/constraints-3.10.txt create mode 100644 owl-bot-staging/grafeas/v1/testing/constraints-3.11.txt create mode 100644 owl-bot-staging/grafeas/v1/testing/constraints-3.12.txt create mode 100644 owl-bot-staging/grafeas/v1/testing/constraints-3.13.txt create mode 100644 owl-bot-staging/grafeas/v1/testing/constraints-3.7.txt create mode 100644 owl-bot-staging/grafeas/v1/testing/constraints-3.8.txt create mode 100644 owl-bot-staging/grafeas/v1/testing/constraints-3.9.txt create mode 100644 owl-bot-staging/grafeas/v1/tests/__init__.py create mode 100644 owl-bot-staging/grafeas/v1/tests/unit/__init__.py create mode 100644 owl-bot-staging/grafeas/v1/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/grafeas/v1/tests/unit/gapic/grafeas_v1/__init__.py create mode 100644 owl-bot-staging/grafeas/v1/tests/unit/gapic/grafeas_v1/test_grafeas.py diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/.coveragerc b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/.coveragerc new file mode 100644 index 000000000000..dafc77479871 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/shopping/merchant_promotions/__init__.py + google/shopping/merchant_promotions/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/google-shopping-merchant-promotions/v1beta/.flake8 b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/.flake8 new file mode 100644 index 000000000000..29227d4cf419 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/.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/google-shopping-merchant-promotions/v1beta/MANIFEST.in b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/MANIFEST.in new file mode 100644 index 000000000000..4000aef85aac --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include google/shopping/merchant_promotions *.py +recursive-include google/shopping/merchant_promotions_v1beta *.py diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/README.rst b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/README.rst new file mode 100644 index 000000000000..cb2860617dd9 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/README.rst @@ -0,0 +1,49 @@ +Python Client for Google Shopping Merchant Promotions 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 Shopping Merchant Promotions 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/google-shopping-merchant-promotions/v1beta/docs/_static/custom.css b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/_static/custom.css new file mode 100644 index 000000000000..06423be0b592 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/_static/custom.css @@ -0,0 +1,3 @@ +dl.field-list > dt { + min-width: 100px +} diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/conf.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/conf.py new file mode 100644 index 000000000000..903cf3292f1b --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/conf.py @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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-shopping-merchant-promotions 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-shopping-merchant-promotions" +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 Shopping 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-shopping-merchant-promotions-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-shopping-merchant-promotions.tex", + u"google-shopping-merchant-promotions 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-shopping-merchant-promotions", + u"Google Shopping Merchant Promotions 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-shopping-merchant-promotions", + u"google-shopping-merchant-promotions Documentation", + author, + "google-shopping-merchant-promotions", + "GAPIC library for Google Shopping Merchant Promotions 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/google-shopping-merchant-promotions/v1beta/docs/index.rst b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/index.rst new file mode 100644 index 000000000000..bd406fae2308 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + merchant_promotions_v1beta/services_ + merchant_promotions_v1beta/types_ diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/promotions_service.rst b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/promotions_service.rst new file mode 100644 index 000000000000..229477aebf39 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/promotions_service.rst @@ -0,0 +1,10 @@ +PromotionsService +----------------------------------- + +.. automodule:: google.shopping.merchant_promotions_v1beta.services.promotions_service + :members: + :inherited-members: + +.. automodule:: google.shopping.merchant_promotions_v1beta.services.promotions_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/services_.rst b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/services_.rst new file mode 100644 index 000000000000..befbacf009f8 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/services_.rst @@ -0,0 +1,6 @@ +Services for Google Shopping Merchant Promotions v1beta API +=========================================================== +.. toctree:: + :maxdepth: 2 + + promotions_service diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/types_.rst b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/types_.rst new file mode 100644 index 000000000000..a95c03a1e319 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/types_.rst @@ -0,0 +1,6 @@ +Types for Google Shopping Merchant Promotions v1beta API +======================================================== + +.. automodule:: google.shopping.merchant_promotions_v1beta.types + :members: + :show-inheritance: diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/__init__.py new file mode 100644 index 000000000000..443803dbb301 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/__init__.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.shopping.merchant_promotions import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.shopping.merchant_promotions_v1beta.services.promotions_service.client import PromotionsServiceClient +from google.shopping.merchant_promotions_v1beta.services.promotions_service.async_client import PromotionsServiceAsyncClient + +from google.shopping.merchant_promotions_v1beta.types.promotions import GetPromotionRequest +from google.shopping.merchant_promotions_v1beta.types.promotions import InsertPromotionRequest +from google.shopping.merchant_promotions_v1beta.types.promotions import ListPromotionsRequest +from google.shopping.merchant_promotions_v1beta.types.promotions import ListPromotionsResponse +from google.shopping.merchant_promotions_v1beta.types.promotions import Promotion +from google.shopping.merchant_promotions_v1beta.types.promotions_common import Attributes +from google.shopping.merchant_promotions_v1beta.types.promotions_common import PromotionStatus +from google.shopping.merchant_promotions_v1beta.types.promotions_common import CouponValueType +from google.shopping.merchant_promotions_v1beta.types.promotions_common import OfferType +from google.shopping.merchant_promotions_v1beta.types.promotions_common import ProductApplicability +from google.shopping.merchant_promotions_v1beta.types.promotions_common import RedemptionChannel +from google.shopping.merchant_promotions_v1beta.types.promotions_common import StoreApplicability + +__all__ = ('PromotionsServiceClient', + 'PromotionsServiceAsyncClient', + 'GetPromotionRequest', + 'InsertPromotionRequest', + 'ListPromotionsRequest', + 'ListPromotionsResponse', + 'Promotion', + 'Attributes', + 'PromotionStatus', + 'CouponValueType', + 'OfferType', + 'ProductApplicability', + 'RedemptionChannel', + 'StoreApplicability', +) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/gapic_version.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/gapic_version.py new file mode 100644 index 000000000000..558c8aab67c5 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/py.typed b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/py.typed new file mode 100644 index 000000000000..53f2425ea9b3 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-shopping-merchant-promotions package uses inline types. diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/__init__.py new file mode 100644 index 000000000000..d93e5699df4b --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/__init__.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.shopping.merchant_promotions_v1beta import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.promotions_service import PromotionsServiceClient +from .services.promotions_service import PromotionsServiceAsyncClient + +from .types.promotions import GetPromotionRequest +from .types.promotions import InsertPromotionRequest +from .types.promotions import ListPromotionsRequest +from .types.promotions import ListPromotionsResponse +from .types.promotions import Promotion +from .types.promotions_common import Attributes +from .types.promotions_common import PromotionStatus +from .types.promotions_common import CouponValueType +from .types.promotions_common import OfferType +from .types.promotions_common import ProductApplicability +from .types.promotions_common import RedemptionChannel +from .types.promotions_common import StoreApplicability + +__all__ = ( + 'PromotionsServiceAsyncClient', +'Attributes', +'CouponValueType', +'GetPromotionRequest', +'InsertPromotionRequest', +'ListPromotionsRequest', +'ListPromotionsResponse', +'OfferType', +'ProductApplicability', +'Promotion', +'PromotionStatus', +'PromotionsServiceClient', +'RedemptionChannel', +'StoreApplicability', +) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_metadata.json b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_metadata.json new file mode 100644 index 000000000000..0f9f123e2e18 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_metadata.json @@ -0,0 +1,73 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.shopping.merchant_promotions_v1beta", + "protoPackage": "google.shopping.merchant.promotions.v1beta", + "schema": "1.0", + "services": { + "PromotionsService": { + "clients": { + "grpc": { + "libraryClient": "PromotionsServiceClient", + "rpcs": { + "GetPromotion": { + "methods": [ + "get_promotion" + ] + }, + "InsertPromotion": { + "methods": [ + "insert_promotion" + ] + }, + "ListPromotions": { + "methods": [ + "list_promotions" + ] + } + } + }, + "grpc-async": { + "libraryClient": "PromotionsServiceAsyncClient", + "rpcs": { + "GetPromotion": { + "methods": [ + "get_promotion" + ] + }, + "InsertPromotion": { + "methods": [ + "insert_promotion" + ] + }, + "ListPromotions": { + "methods": [ + "list_promotions" + ] + } + } + }, + "rest": { + "libraryClient": "PromotionsServiceClient", + "rpcs": { + "GetPromotion": { + "methods": [ + "get_promotion" + ] + }, + "InsertPromotion": { + "methods": [ + "insert_promotion" + ] + }, + "ListPromotions": { + "methods": [ + "list_promotions" + ] + } + } + } + } + } + } +} diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_version.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_version.py new file mode 100644 index 000000000000..558c8aab67c5 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/py.typed b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/py.typed new file mode 100644 index 000000000000..53f2425ea9b3 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-shopping-merchant-promotions package uses inline types. diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/__init__.py new file mode 100644 index 000000000000..8f6cf068242c --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/__init__.py new file mode 100644 index 000000000000..3cebeff587b6 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 PromotionsServiceClient +from .async_client import PromotionsServiceAsyncClient + +__all__ = ( + 'PromotionsServiceClient', + 'PromotionsServiceAsyncClient', +) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/async_client.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/async_client.py new file mode 100644 index 000000000000..eeb2a4e1d005 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/async_client.py @@ -0,0 +1,584 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 re +from typing import Dict, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.shopping.merchant_promotions_v1beta 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_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.shopping.merchant_promotions_v1beta.services.promotions_service import pagers +from google.shopping.merchant_promotions_v1beta.types import promotions +from google.shopping.merchant_promotions_v1beta.types import promotions_common +from google.shopping.type.types import types +from .transports.base import PromotionsServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import PromotionsServiceGrpcAsyncIOTransport +from .client import PromotionsServiceClient + + +class PromotionsServiceAsyncClient: + """Service to manage promotions for products.""" + + _client: PromotionsServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = PromotionsServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = PromotionsServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = PromotionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = PromotionsServiceClient._DEFAULT_UNIVERSE + + promotion_path = staticmethod(PromotionsServiceClient.promotion_path) + parse_promotion_path = staticmethod(PromotionsServiceClient.parse_promotion_path) + common_billing_account_path = staticmethod(PromotionsServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(PromotionsServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(PromotionsServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(PromotionsServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(PromotionsServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(PromotionsServiceClient.parse_common_organization_path) + common_project_path = staticmethod(PromotionsServiceClient.common_project_path) + parse_common_project_path = staticmethod(PromotionsServiceClient.parse_common_project_path) + common_location_path = staticmethod(PromotionsServiceClient.common_location_path) + parse_common_location_path = staticmethod(PromotionsServiceClient.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: + PromotionsServiceAsyncClient: The constructed client. + """ + return PromotionsServiceClient.from_service_account_info.__func__(PromotionsServiceAsyncClient, 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: + PromotionsServiceAsyncClient: The constructed client. + """ + return PromotionsServiceClient.from_service_account_file.__func__(PromotionsServiceAsyncClient, 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 PromotionsServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> PromotionsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + PromotionsServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = PromotionsServiceClient.get_transport_class + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, PromotionsServiceTransport, Callable[..., PromotionsServiceTransport]]] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the promotions service async 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 (Optional[Union[str,PromotionsServiceTransport,Callable[..., PromotionsServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the PromotionsServiceTransport constructor. + 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. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client = PromotionsServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def insert_promotion(self, + request: Optional[Union[promotions.InsertPromotionRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> promotions.Promotion: + r"""Inserts a promotion for your Merchant Center account. + If the promotion already exists, then it updates the + promotion instead. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.shopping import merchant_promotions_v1beta + + async def sample_insert_promotion(): + # Create a client + client = merchant_promotions_v1beta.PromotionsServiceAsyncClient() + + # Initialize request argument(s) + promotion = merchant_promotions_v1beta.Promotion() + promotion.promotion_id = "promotion_id_value" + promotion.content_language = "content_language_value" + promotion.target_country = "target_country_value" + promotion.redemption_channel = ['ONLINE'] + + request = merchant_promotions_v1beta.InsertPromotionRequest( + parent="parent_value", + promotion=promotion, + data_source="data_source_value", + ) + + # Make the request + response = await client.insert_promotion(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.shopping.merchant_promotions_v1beta.types.InsertPromotionRequest, dict]]): + The request object. Request message for the ``InsertPromotion`` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.shopping.merchant_promotions_v1beta.types.Promotion: + Represents a promotion. See the following articles for + more details. + + Required promotion input attributes to pass data + validation checks are primarily defined below: + + \* [Promotions data + specification](\ https://support.google.com/merchants/answer/2906014) + \* [Local promotions data + specification](\ https://support.google.com/merchants/answer/10146130) + + After inserting, updating a promotion input, it may + take several minutes before the final promotion can + be retrieved. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, promotions.InsertPromotionRequest): + request = promotions.InsertPromotionRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[self._client._transport.insert_promotion] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_promotion(self, + request: Optional[Union[promotions.GetPromotionRequest, 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]] = (), + ) -> promotions.Promotion: + r"""Retrieves the promotion from your Merchant Center + account. + After inserting or updating a promotion input, it may + take several minutes before the updated promotion can be + retrieved. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.shopping import merchant_promotions_v1beta + + async def sample_get_promotion(): + # Create a client + client = merchant_promotions_v1beta.PromotionsServiceAsyncClient() + + # Initialize request argument(s) + request = merchant_promotions_v1beta.GetPromotionRequest( + name="name_value", + ) + + # Make the request + response = await client.get_promotion(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.shopping.merchant_promotions_v1beta.types.GetPromotionRequest, dict]]): + The request object. Request message for the ``GetPromotion`` method. + name (:class:`str`): + Required. The name of the promotion to retrieve. Format: + ``accounts/{account}/promotions/{promotions}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.shopping.merchant_promotions_v1beta.types.Promotion: + Represents a promotion. See the following articles for + more details. + + Required promotion input attributes to pass data + validation checks are primarily defined below: + + \* [Promotions data + specification](\ https://support.google.com/merchants/answer/2906014) + \* [Local promotions data + specification](\ https://support.google.com/merchants/answer/10146130) + + After inserting, updating a promotion input, it may + take several minutes before the final promotion can + be retrieved. + + """ + # Create or coerce a protobuf request object. + # - Quick 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.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, promotions.GetPromotionRequest): + request = promotions.GetPromotionRequest(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._client._transport._wrapped_methods[self._client._transport.get_promotion] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_promotions(self, + request: Optional[Union[promotions.ListPromotionsRequest, 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.ListPromotionsAsyncPager: + r"""Lists the promotions in your Merchant Center account. The + response might contain fewer items than specified by + ``pageSize``. Rely on ``pageToken`` to determine if there are + more items to be requested. + + After inserting or updating a promotion, it may take several + minutes before the updated processed promotion can be retrieved. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.shopping import merchant_promotions_v1beta + + async def sample_list_promotions(): + # Create a client + client = merchant_promotions_v1beta.PromotionsServiceAsyncClient() + + # Initialize request argument(s) + request = merchant_promotions_v1beta.ListPromotionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_promotions(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.shopping.merchant_promotions_v1beta.types.ListPromotionsRequest, dict]]): + The request object. Request message for the ``ListPromotions`` method. + parent (:class:`str`): + Required. The account to list processed promotions for. + Format: ``accounts/{account}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.shopping.merchant_promotions_v1beta.services.promotions_service.pagers.ListPromotionsAsyncPager: + Response message for the ListPromotions 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.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, promotions.ListPromotionsRequest): + request = promotions.ListPromotionsRequest(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._client._transport._wrapped_methods[self._client._transport.list_promotions] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListPromotionsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "PromotionsServiceAsyncClient": + 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__ = ( + "PromotionsServiceAsyncClient", +) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/client.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/client.py new file mode 100644 index 000000000000..9ef22e707369 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/client.py @@ -0,0 +1,939 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.shopping.merchant_promotions_v1beta 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, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +from google.shopping.merchant_promotions_v1beta.services.promotions_service import pagers +from google.shopping.merchant_promotions_v1beta.types import promotions +from google.shopping.merchant_promotions_v1beta.types import promotions_common +from google.shopping.type.types import types +from .transports.base import PromotionsServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import PromotionsServiceGrpcTransport +from .transports.grpc_asyncio import PromotionsServiceGrpcAsyncIOTransport +from .transports.rest import PromotionsServiceRestTransport + + +class PromotionsServiceClientMeta(type): + """Metaclass for the PromotionsService 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[PromotionsServiceTransport]] + _transport_registry["grpc"] = PromotionsServiceGrpcTransport + _transport_registry["grpc_asyncio"] = PromotionsServiceGrpcAsyncIOTransport + _transport_registry["rest"] = PromotionsServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[PromotionsServiceTransport]: + """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 PromotionsServiceClient(metaclass=PromotionsServiceClientMeta): + """Service to manage promotions for products.""" + + @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") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "merchantapi.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "merchantapi.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @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: + PromotionsServiceClient: 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: + PromotionsServiceClient: 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) -> PromotionsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + PromotionsServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def promotion_path(account: str,promotion: str,) -> str: + """Returns a fully-qualified promotion string.""" + return "accounts/{account}/promotions/{promotion}".format(account=account, promotion=promotion, ) + + @staticmethod + def parse_promotion_path(path: str) -> Dict[str,str]: + """Parses a promotion path into its component segments.""" + m = re.match(r"^accounts/(?P.+?)/promotions/(?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): + """Deprecated. 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. + """ + + warnings.warn("get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning) + 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 + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false").lower() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + 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`") + return use_client_cert == "true", use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint(api_override, client_cert_source, universe_domain, use_mtls_endpoint): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + _default_universe = PromotionsServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError(f"mTLS is not supported in any universe other than {_default_universe}.") + api_endpoint = PromotionsServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = PromotionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=universe_domain) + return api_endpoint + + @staticmethod + def _get_universe_domain(client_universe_domain: Optional[str], universe_domain_env: Optional[str]) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = PromotionsServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + @staticmethod + def _compare_universes(client_universe: str, + credentials: ga_credentials.Credentials) -> bool: + """Returns True iff the universe domains used by the client and credentials match. + + Args: + client_universe (str): The universe domain configured via the client options. + credentials (ga_credentials.Credentials): The credentials being used in the client. + + Returns: + bool: True iff client_universe matches the universe in credentials. + + Raises: + ValueError: when client_universe does not match the universe in credentials. + """ + + default_universe = PromotionsServiceClient._DEFAULT_UNIVERSE + credentials_universe = getattr(credentials, "universe_domain", default_universe) + + if client_universe != credentials_universe: + raise ValueError("The configured universe domain " + f"({client_universe}) does not match the universe domain " + f"found in the credentials ({credentials_universe}). " + "If you haven't configured the universe domain explicitly, " + f"`{default_universe}` is the default.") + return True + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + self._is_universe_domain_valid = (self._is_universe_domain_valid or + PromotionsServiceClient._compare_universes(self.universe_domain, self.transport._credentials)) + return self._is_universe_domain_valid + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, PromotionsServiceTransport, Callable[..., PromotionsServiceTransport]]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the promotions 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 (Optional[Union[str,PromotionsServiceTransport,Callable[..., PromotionsServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the PromotionsServiceTransport constructor. + 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. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast(client_options_lib.ClientOptions, self._client_options) + + universe_domain_opt = getattr(self._client_options, 'universe_domain', None) + + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = PromotionsServiceClient._read_environment_variables() + self._client_cert_source = PromotionsServiceClient._get_client_cert_source(self._client_options.client_cert_source, self._use_client_cert) + self._universe_domain = PromotionsServiceClient._get_universe_domain(universe_domain_opt, self._universe_domain_env) + self._api_endpoint = None # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + api_key_value = getattr(self._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. + transport_provided = isinstance(transport, PromotionsServiceTransport) + if transport_provided: + # transport is a PromotionsServiceTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(PromotionsServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = (self._api_endpoint or + PromotionsServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint)) + + if not transport_provided: + 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_init: Union[Type[PromotionsServiceTransport], Callable[..., PromotionsServiceTransport]] = ( + PromotionsServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., PromotionsServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + def insert_promotion(self, + request: Optional[Union[promotions.InsertPromotionRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> promotions.Promotion: + r"""Inserts a promotion for your Merchant Center account. + If the promotion already exists, then it updates the + promotion instead. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.shopping import merchant_promotions_v1beta + + def sample_insert_promotion(): + # Create a client + client = merchant_promotions_v1beta.PromotionsServiceClient() + + # Initialize request argument(s) + promotion = merchant_promotions_v1beta.Promotion() + promotion.promotion_id = "promotion_id_value" + promotion.content_language = "content_language_value" + promotion.target_country = "target_country_value" + promotion.redemption_channel = ['ONLINE'] + + request = merchant_promotions_v1beta.InsertPromotionRequest( + parent="parent_value", + promotion=promotion, + data_source="data_source_value", + ) + + # Make the request + response = client.insert_promotion(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.shopping.merchant_promotions_v1beta.types.InsertPromotionRequest, dict]): + The request object. Request message for the ``InsertPromotion`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.shopping.merchant_promotions_v1beta.types.Promotion: + Represents a promotion. See the following articles for + more details. + + Required promotion input attributes to pass data + validation checks are primarily defined below: + + \* [Promotions data + specification](\ https://support.google.com/merchants/answer/2906014) + \* [Local promotions data + specification](\ https://support.google.com/merchants/answer/10146130) + + After inserting, updating a promotion input, it may + take several minutes before the final promotion can + be retrieved. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, promotions.InsertPromotionRequest): + request = promotions.InsertPromotionRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.insert_promotion] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_promotion(self, + request: Optional[Union[promotions.GetPromotionRequest, 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]] = (), + ) -> promotions.Promotion: + r"""Retrieves the promotion from your Merchant Center + account. + After inserting or updating a promotion input, it may + take several minutes before the updated promotion can be + retrieved. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.shopping import merchant_promotions_v1beta + + def sample_get_promotion(): + # Create a client + client = merchant_promotions_v1beta.PromotionsServiceClient() + + # Initialize request argument(s) + request = merchant_promotions_v1beta.GetPromotionRequest( + name="name_value", + ) + + # Make the request + response = client.get_promotion(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.shopping.merchant_promotions_v1beta.types.GetPromotionRequest, dict]): + The request object. Request message for the ``GetPromotion`` method. + name (str): + Required. The name of the promotion to retrieve. Format: + ``accounts/{account}/promotions/{promotions}`` + + 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.shopping.merchant_promotions_v1beta.types.Promotion: + Represents a promotion. See the following articles for + more details. + + Required promotion input attributes to pass data + validation checks are primarily defined below: + + \* [Promotions data + specification](\ https://support.google.com/merchants/answer/2906014) + \* [Local promotions data + specification](\ https://support.google.com/merchants/answer/10146130) + + After inserting, updating a promotion input, it may + take several minutes before the final promotion can + be retrieved. + + """ + # Create or coerce a protobuf request object. + # - Quick 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.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, promotions.GetPromotionRequest): + request = promotions.GetPromotionRequest(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_promotion] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_promotions(self, + request: Optional[Union[promotions.ListPromotionsRequest, 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.ListPromotionsPager: + r"""Lists the promotions in your Merchant Center account. The + response might contain fewer items than specified by + ``pageSize``. Rely on ``pageToken`` to determine if there are + more items to be requested. + + After inserting or updating a promotion, it may take several + minutes before the updated processed promotion can be retrieved. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.shopping import merchant_promotions_v1beta + + def sample_list_promotions(): + # Create a client + client = merchant_promotions_v1beta.PromotionsServiceClient() + + # Initialize request argument(s) + request = merchant_promotions_v1beta.ListPromotionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_promotions(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.shopping.merchant_promotions_v1beta.types.ListPromotionsRequest, dict]): + The request object. Request message for the ``ListPromotions`` method. + parent (str): + Required. The account to list processed promotions for. + Format: ``accounts/{account}`` + + 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.shopping.merchant_promotions_v1beta.services.promotions_service.pagers.ListPromotionsPager: + Response message for the ListPromotions 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.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, promotions.ListPromotionsRequest): + request = promotions.ListPromotionsRequest(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_promotions] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListPromotionsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "PromotionsServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "PromotionsServiceClient", +) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/pagers.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/pagers.py new file mode 100644 index 000000000000..df04944c3a32 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/pagers.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async +from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator, Union +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.shopping.merchant_promotions_v1beta.types import promotions + + +class ListPromotionsPager: + """A pager for iterating through ``list_promotions`` requests. + + This class thinly wraps an initial + :class:`google.shopping.merchant_promotions_v1beta.types.ListPromotionsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``promotions`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListPromotions`` requests and continue to iterate + through the ``promotions`` field on the + corresponding responses. + + All the usual :class:`google.shopping.merchant_promotions_v1beta.types.ListPromotionsResponse` + 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[..., promotions.ListPromotionsResponse], + request: promotions.ListPromotionsRequest, + response: promotions.ListPromotionsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.shopping.merchant_promotions_v1beta.types.ListPromotionsRequest): + The initial request object. + response (google.shopping.merchant_promotions_v1beta.types.ListPromotionsResponse): + The initial response object. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = promotions.ListPromotionsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[promotions.ListPromotionsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, retry=self._retry, timeout=self._timeout, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[promotions.Promotion]: + for page in self.pages: + yield from page.promotions + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListPromotionsAsyncPager: + """A pager for iterating through ``list_promotions`` requests. + + This class thinly wraps an initial + :class:`google.shopping.merchant_promotions_v1beta.types.ListPromotionsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``promotions`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListPromotions`` requests and continue to iterate + through the ``promotions`` field on the + corresponding responses. + + All the usual :class:`google.shopping.merchant_promotions_v1beta.types.ListPromotionsResponse` + 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[promotions.ListPromotionsResponse]], + request: promotions.ListPromotionsRequest, + response: promotions.ListPromotionsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.shopping.merchant_promotions_v1beta.types.ListPromotionsRequest): + The initial request object. + response (google.shopping.merchant_promotions_v1beta.types.ListPromotionsResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = promotions.ListPromotionsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[promotions.ListPromotionsResponse]: + 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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[promotions.Promotion]: + async def async_generator(): + async for page in self.pages: + for response in page.promotions: + 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/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/README.rst b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/README.rst new file mode 100644 index 000000000000..8e430c8e2e3a --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`PromotionsServiceTransport` is the ABC for all transports. +- public child `PromotionsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `PromotionsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BasePromotionsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `PromotionsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/__init__.py new file mode 100644 index 000000000000..6f04436b2cd7 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 PromotionsServiceTransport +from .grpc import PromotionsServiceGrpcTransport +from .grpc_asyncio import PromotionsServiceGrpcAsyncIOTransport +from .rest import PromotionsServiceRestTransport +from .rest import PromotionsServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[PromotionsServiceTransport]] +_transport_registry['grpc'] = PromotionsServiceGrpcTransport +_transport_registry['grpc_asyncio'] = PromotionsServiceGrpcAsyncIOTransport +_transport_registry['rest'] = PromotionsServiceRestTransport + +__all__ = ( + 'PromotionsServiceTransport', + 'PromotionsServiceGrpcTransport', + 'PromotionsServiceGrpcAsyncIOTransport', + 'PromotionsServiceRestTransport', + 'PromotionsServiceRestInterceptor', +) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/base.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/base.py new file mode 100644 index 000000000000..7890c6625a55 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/base.py @@ -0,0 +1,182 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.shopping.merchant_promotions_v1beta 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.shopping.merchant_promotions_v1beta.types import promotions + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class PromotionsServiceTransport(abc.ABC): + """Abstract transport class for PromotionsService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/content', + ) + + DEFAULT_HOST: str = 'merchantapi.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 (default: 'merchantapi.googleapis.com'). + 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 not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # 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 and not self._ignore_credentials: + 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 + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.insert_promotion: gapic_v1.method.wrap_method( + self.insert_promotion, + default_timeout=None, + client_info=client_info, + ), + self.get_promotion: gapic_v1.method.wrap_method( + self.get_promotion, + default_timeout=None, + client_info=client_info, + ), + self.list_promotions: gapic_v1.method.wrap_method( + self.list_promotions, + 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 insert_promotion(self) -> Callable[ + [promotions.InsertPromotionRequest], + Union[ + promotions.Promotion, + Awaitable[promotions.Promotion] + ]]: + raise NotImplementedError() + + @property + def get_promotion(self) -> Callable[ + [promotions.GetPromotionRequest], + Union[ + promotions.Promotion, + Awaitable[promotions.Promotion] + ]]: + raise NotImplementedError() + + @property + def list_promotions(self) -> Callable[ + [promotions.ListPromotionsRequest], + Union[ + promotions.ListPromotionsResponse, + Awaitable[promotions.ListPromotionsResponse] + ]]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'PromotionsServiceTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc.py new file mode 100644 index 000000000000..717c5da1e20e --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc.py @@ -0,0 +1,334 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.shopping.merchant_promotions_v1beta.types import promotions +from .base import PromotionsServiceTransport, DEFAULT_CLIENT_INFO + + +class PromotionsServiceGrpcTransport(PromotionsServiceTransport): + """gRPC backend transport for PromotionsService. + + Service to manage promotions for products. + + 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 = 'merchantapi.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[grpc.Channel, Callable[..., 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 (default: 'merchantapi.googleapis.com'). + 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 a ``channel`` instance 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 a ``channel`` instance is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # 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: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + 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 = 'merchantapi.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 insert_promotion(self) -> Callable[ + [promotions.InsertPromotionRequest], + promotions.Promotion]: + r"""Return a callable for the insert promotion method over gRPC. + + Inserts a promotion for your Merchant Center account. + If the promotion already exists, then it updates the + promotion instead. + + Returns: + Callable[[~.InsertPromotionRequest], + ~.Promotion]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'insert_promotion' not in self._stubs: + self._stubs['insert_promotion'] = self.grpc_channel.unary_unary( + '/google.shopping.merchant.promotions.v1beta.PromotionsService/InsertPromotion', + request_serializer=promotions.InsertPromotionRequest.serialize, + response_deserializer=promotions.Promotion.deserialize, + ) + return self._stubs['insert_promotion'] + + @property + def get_promotion(self) -> Callable[ + [promotions.GetPromotionRequest], + promotions.Promotion]: + r"""Return a callable for the get promotion method over gRPC. + + Retrieves the promotion from your Merchant Center + account. + After inserting or updating a promotion input, it may + take several minutes before the updated promotion can be + retrieved. + + Returns: + Callable[[~.GetPromotionRequest], + ~.Promotion]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_promotion' not in self._stubs: + self._stubs['get_promotion'] = self.grpc_channel.unary_unary( + '/google.shopping.merchant.promotions.v1beta.PromotionsService/GetPromotion', + request_serializer=promotions.GetPromotionRequest.serialize, + response_deserializer=promotions.Promotion.deserialize, + ) + return self._stubs['get_promotion'] + + @property + def list_promotions(self) -> Callable[ + [promotions.ListPromotionsRequest], + promotions.ListPromotionsResponse]: + r"""Return a callable for the list promotions method over gRPC. + + Lists the promotions in your Merchant Center account. The + response might contain fewer items than specified by + ``pageSize``. Rely on ``pageToken`` to determine if there are + more items to be requested. + + After inserting or updating a promotion, it may take several + minutes before the updated processed promotion can be retrieved. + + Returns: + Callable[[~.ListPromotionsRequest], + ~.ListPromotionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_promotions' not in self._stubs: + self._stubs['list_promotions'] = self.grpc_channel.unary_unary( + '/google.shopping.merchant.promotions.v1beta.PromotionsService/ListPromotions', + request_serializer=promotions.ListPromotionsRequest.serialize, + response_deserializer=promotions.ListPromotionsResponse.deserialize, + ) + return self._stubs['list_promotions'] + + def close(self): + self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'PromotionsServiceGrpcTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py new file mode 100644 index 000000000000..b149875ac0a0 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py @@ -0,0 +1,365 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 inspect +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 exceptions as core_exceptions +from google.api_core import retry_async as retries +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.shopping.merchant_promotions_v1beta.types import promotions +from .base import PromotionsServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import PromotionsServiceGrpcTransport + + +class PromotionsServiceGrpcAsyncIOTransport(PromotionsServiceTransport): + """gRPC AsyncIO backend transport for PromotionsService. + + Service to manage promotions for products. + + 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 = 'merchantapi.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`. + 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 = 'merchantapi.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[aio.Channel, Callable[..., 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 (default: 'merchantapi.googleapis.com'). + 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 a ``channel`` instance 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 a ``channel`` instance 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[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # 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: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + 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._wrap_with_kind = "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + 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 insert_promotion(self) -> Callable[ + [promotions.InsertPromotionRequest], + Awaitable[promotions.Promotion]]: + r"""Return a callable for the insert promotion method over gRPC. + + Inserts a promotion for your Merchant Center account. + If the promotion already exists, then it updates the + promotion instead. + + Returns: + Callable[[~.InsertPromotionRequest], + Awaitable[~.Promotion]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if 'insert_promotion' not in self._stubs: + self._stubs['insert_promotion'] = self.grpc_channel.unary_unary( + '/google.shopping.merchant.promotions.v1beta.PromotionsService/InsertPromotion', + request_serializer=promotions.InsertPromotionRequest.serialize, + response_deserializer=promotions.Promotion.deserialize, + ) + return self._stubs['insert_promotion'] + + @property + def get_promotion(self) -> Callable[ + [promotions.GetPromotionRequest], + Awaitable[promotions.Promotion]]: + r"""Return a callable for the get promotion method over gRPC. + + Retrieves the promotion from your Merchant Center + account. + After inserting or updating a promotion input, it may + take several minutes before the updated promotion can be + retrieved. + + Returns: + Callable[[~.GetPromotionRequest], + Awaitable[~.Promotion]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_promotion' not in self._stubs: + self._stubs['get_promotion'] = self.grpc_channel.unary_unary( + '/google.shopping.merchant.promotions.v1beta.PromotionsService/GetPromotion', + request_serializer=promotions.GetPromotionRequest.serialize, + response_deserializer=promotions.Promotion.deserialize, + ) + return self._stubs['get_promotion'] + + @property + def list_promotions(self) -> Callable[ + [promotions.ListPromotionsRequest], + Awaitable[promotions.ListPromotionsResponse]]: + r"""Return a callable for the list promotions method over gRPC. + + Lists the promotions in your Merchant Center account. The + response might contain fewer items than specified by + ``pageSize``. Rely on ``pageToken`` to determine if there are + more items to be requested. + + After inserting or updating a promotion, it may take several + minutes before the updated processed promotion can be retrieved. + + Returns: + Callable[[~.ListPromotionsRequest], + Awaitable[~.ListPromotionsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_promotions' not in self._stubs: + self._stubs['list_promotions'] = self.grpc_channel.unary_unary( + '/google.shopping.merchant.promotions.v1beta.PromotionsService/ListPromotions', + request_serializer=promotions.ListPromotionsRequest.serialize, + response_deserializer=promotions.ListPromotionsResponse.deserialize, + ) + return self._stubs['list_promotions'] + + def _prep_wrapped_messages(self, client_info): + """ Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.insert_promotion: self._wrap_method( + self.insert_promotion, + default_timeout=None, + client_info=client_info, + ), + self.get_promotion: self._wrap_method( + self.get_promotion, + default_timeout=None, + client_info=client_info, + ), + self.list_promotions: self._wrap_method( + self.list_promotions, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ( + 'PromotionsServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py new file mode 100644 index 000000000000..a58f56329486 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py @@ -0,0 +1,511 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 +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 gapic_v1 + +from google.protobuf import json_format + +from requests import __version__ as requests_version +import dataclasses +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + + +from google.shopping.merchant_promotions_v1beta.types import promotions + + +from .rest_base import _BasePromotionsServiceRestTransport +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + + +class PromotionsServiceRestInterceptor: + """Interceptor for PromotionsService. + + 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 PromotionsServiceRestTransport. + + .. code-block:: python + class MyCustomPromotionsServiceInterceptor(PromotionsServiceRestInterceptor): + def pre_get_promotion(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_promotion(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_insert_promotion(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_insert_promotion(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_promotions(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_promotions(self, response): + logging.log(f"Received response: {response}") + return response + + transport = PromotionsServiceRestTransport(interceptor=MyCustomPromotionsServiceInterceptor()) + client = PromotionsServiceClient(transport=transport) + + + """ + def pre_get_promotion(self, request: promotions.GetPromotionRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[promotions.GetPromotionRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_promotion + + Override in a subclass to manipulate the request or metadata + before they are sent to the PromotionsService server. + """ + return request, metadata + + def post_get_promotion(self, response: promotions.Promotion) -> promotions.Promotion: + """Post-rpc interceptor for get_promotion + + Override in a subclass to manipulate the response + after it is returned by the PromotionsService server but before + it is returned to user code. + """ + return response + + def pre_insert_promotion(self, request: promotions.InsertPromotionRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[promotions.InsertPromotionRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for insert_promotion + + Override in a subclass to manipulate the request or metadata + before they are sent to the PromotionsService server. + """ + return request, metadata + + def post_insert_promotion(self, response: promotions.Promotion) -> promotions.Promotion: + """Post-rpc interceptor for insert_promotion + + Override in a subclass to manipulate the response + after it is returned by the PromotionsService server but before + it is returned to user code. + """ + return response + + def pre_list_promotions(self, request: promotions.ListPromotionsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[promotions.ListPromotionsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_promotions + + Override in a subclass to manipulate the request or metadata + before they are sent to the PromotionsService server. + """ + return request, metadata + + def post_list_promotions(self, response: promotions.ListPromotionsResponse) -> promotions.ListPromotionsResponse: + """Post-rpc interceptor for list_promotions + + Override in a subclass to manipulate the response + after it is returned by the PromotionsService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class PromotionsServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: PromotionsServiceRestInterceptor + + +class PromotionsServiceRestTransport(_BasePromotionsServiceRestTransport): + """REST backend synchronous transport for PromotionsService. + + Service to manage promotions for products. + + 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 = 'merchantapi.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[PromotionsServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + 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 + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + 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 PromotionsServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetPromotion(_BasePromotionsServiceRestTransport._BaseGetPromotion, PromotionsServiceRestStub): + def __hash__(self): + return hash("PromotionsServiceRestTransport.GetPromotion") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__(self, + request: promotions.GetPromotionRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> promotions.Promotion: + r"""Call the get promotion method over HTTP. + + Args: + request (~.promotions.GetPromotionRequest): + The request object. Request message for the ``GetPromotion`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.promotions.Promotion: + Represents a promotion. See the following articles for + more details. + + Required promotion input attributes to pass data + validation checks are primarily defined below: + + - `Promotions data + specification `__ + - `Local promotions data + specification `__ + + After inserting, updating a promotion input, it may take + several minutes before the final promotion can be + retrieved. + + """ + + http_options = _BasePromotionsServiceRestTransport._BaseGetPromotion._get_http_options() + request, metadata = self._interceptor.pre_get_promotion(request, metadata) + transcoded_request = _BasePromotionsServiceRestTransport._BaseGetPromotion._get_transcoded_request(http_options, request) + + # Jsonify the query params + query_params = _BasePromotionsServiceRestTransport._BaseGetPromotion._get_query_params_json(transcoded_request) + + # Send the request + response = PromotionsServiceRestTransport._GetPromotion._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) + + # 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 = promotions.Promotion() + pb_resp = promotions.Promotion.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_promotion(resp) + return resp + + class _InsertPromotion(_BasePromotionsServiceRestTransport._BaseInsertPromotion, PromotionsServiceRestStub): + def __hash__(self): + return hash("PromotionsServiceRestTransport.InsertPromotion") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__(self, + request: promotions.InsertPromotionRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> promotions.Promotion: + r"""Call the insert promotion method over HTTP. + + Args: + request (~.promotions.InsertPromotionRequest): + The request object. Request message for the ``InsertPromotion`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.promotions.Promotion: + Represents a promotion. See the following articles for + more details. + + Required promotion input attributes to pass data + validation checks are primarily defined below: + + - `Promotions data + specification `__ + - `Local promotions data + specification `__ + + After inserting, updating a promotion input, it may take + several minutes before the final promotion can be + retrieved. + + """ + + http_options = _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_http_options() + request, metadata = self._interceptor.pre_insert_promotion(request, metadata) + transcoded_request = _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_transcoded_request(http_options, request) + + body = _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_request_body_json(transcoded_request) + + # Jsonify the query params + query_params = _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_query_params_json(transcoded_request) + + # Send the request + response = PromotionsServiceRestTransport._InsertPromotion._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = promotions.Promotion() + pb_resp = promotions.Promotion.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_insert_promotion(resp) + return resp + + class _ListPromotions(_BasePromotionsServiceRestTransport._BaseListPromotions, PromotionsServiceRestStub): + def __hash__(self): + return hash("PromotionsServiceRestTransport.ListPromotions") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__(self, + request: promotions.ListPromotionsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> promotions.ListPromotionsResponse: + r"""Call the list promotions method over HTTP. + + Args: + request (~.promotions.ListPromotionsRequest): + The request object. Request message for the ``ListPromotions`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.promotions.ListPromotionsResponse: + Response message for the ``ListPromotions`` method. + """ + + http_options = _BasePromotionsServiceRestTransport._BaseListPromotions._get_http_options() + request, metadata = self._interceptor.pre_list_promotions(request, metadata) + transcoded_request = _BasePromotionsServiceRestTransport._BaseListPromotions._get_transcoded_request(http_options, request) + + # Jsonify the query params + query_params = _BasePromotionsServiceRestTransport._BaseListPromotions._get_query_params_json(transcoded_request) + + # Send the request + response = PromotionsServiceRestTransport._ListPromotions._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) + + # 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 = promotions.ListPromotionsResponse() + pb_resp = promotions.ListPromotionsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_promotions(resp) + return resp + + @property + def get_promotion(self) -> Callable[ + [promotions.GetPromotionRequest], + promotions.Promotion]: + # 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._GetPromotion(self._session, self._host, self._interceptor) # type: ignore + + @property + def insert_promotion(self) -> Callable[ + [promotions.InsertPromotionRequest], + promotions.Promotion]: + # 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._InsertPromotion(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_promotions(self) -> Callable[ + [promotions.ListPromotionsRequest], + promotions.ListPromotionsResponse]: + # 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._ListPromotions(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'PromotionsServiceRestTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest_base.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest_base.py new file mode 100644 index 000000000000..aab3dec4695e --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest_base.py @@ -0,0 +1,212 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 json # type: ignore +from google.api_core import path_template +from google.api_core import gapic_v1 + +from google.protobuf import json_format +from .base import PromotionsServiceTransport, DEFAULT_CLIENT_INFO + +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + + +from google.shopping.merchant_promotions_v1beta.types import promotions + + +class _BasePromotionsServiceRestTransport(PromotionsServiceTransport): + """Base REST backend transport for PromotionsService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + 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 = 'merchantapi.googleapis.com', + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = 'https', + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): 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. + 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 + 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 + ) + + class _BaseGetPromotion: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/promotions/v1beta/{name=accounts/*/promotions/*}', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = promotions.GetPromotionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BasePromotionsServiceRestTransport._BaseGetPromotion._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseInsertPromotion: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/promotions/v1beta/{parent=accounts/*}/promotions:insert', + 'body': '*', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = promotions.InsertPromotionRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + use_integers_for_enums=True + ) + return body + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BasePromotionsServiceRestTransport._BaseInsertPromotion._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListPromotions: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/promotions/v1beta/{parent=accounts/*}/promotions', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = promotions.ListPromotionsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BasePromotionsServiceRestTransport._BaseListPromotions._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__=( + '_BasePromotionsServiceRestTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/__init__.py new file mode 100644 index 000000000000..aa349ec9d51f --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/__init__.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .promotions import ( + GetPromotionRequest, + InsertPromotionRequest, + ListPromotionsRequest, + ListPromotionsResponse, + Promotion, +) +from .promotions_common import ( + Attributes, + PromotionStatus, + CouponValueType, + OfferType, + ProductApplicability, + RedemptionChannel, + StoreApplicability, +) + +__all__ = ( + 'GetPromotionRequest', + 'InsertPromotionRequest', + 'ListPromotionsRequest', + 'ListPromotionsResponse', + 'Promotion', + 'Attributes', + 'PromotionStatus', + 'CouponValueType', + 'OfferType', + 'ProductApplicability', + 'RedemptionChannel', + 'StoreApplicability', +) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions.py new file mode 100644 index 000000000000..d3d9283e4324 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions.py @@ -0,0 +1,277 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.shopping.merchant_promotions_v1beta.types import promotions_common +from google.shopping.type.types import types + + +__protobuf__ = proto.module( + package='google.shopping.merchant.promotions.v1beta', + manifest={ + 'Promotion', + 'InsertPromotionRequest', + 'GetPromotionRequest', + 'ListPromotionsRequest', + 'ListPromotionsResponse', + }, +) + + +class Promotion(proto.Message): + r"""Represents a promotion. See the following articles for more details. + + Required promotion input attributes to pass data validation checks + are primarily defined below: + + - `Promotions data + specification `__ + - `Local promotions data + specification `__ + + After inserting, updating a promotion input, it may take several + minutes before the final promotion can be retrieved. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The name of the promotion. Format: + ``accounts/{account}/promotions/{promotion}`` + promotion_id (str): + Required. The user provided promotion ID to uniquely + identify the promotion. Follow `minimum + requirements `__ + to prevent promotion disapprovals. + content_language (str): + Required. The two-letter `ISO + 639-1 `__ language + code for the promotion. + + Promotions is only for `selected + languages `__. + target_country (str): + Required. The target country used as part of the unique + identifier. Represented as a `CLDR territory + code `__. + + Promotions are only available in selected countries, `Free + Listings and Shopping + ads `__ + `Local Inventory + ads `__ + redemption_channel (MutableSequence[google.shopping.merchant_promotions_v1beta.types.RedemptionChannel]): + Required. `Redemption + channel `__ + for the promotion. At least one channel is required. + data_source (str): + Output only. The primary data source of the + promotion. + attributes (google.shopping.merchant_promotions_v1beta.types.Attributes): + Optional. A list of promotion attributes. + custom_attributes (MutableSequence[google.shopping.type.types.CustomAttribute]): + Optional. A list of custom (merchant-provided) attributes. + It can also be used for submitting any attribute of the data + specification in its generic form (for example, + ``{ "name": "size type", "value": "regular" }``). This is + useful for submitting attributes not explicitly exposed by + the API. + promotion_status (google.shopping.merchant_promotions_v1beta.types.PromotionStatus): + Output only. The `status of a + promotion `__, + data validation issues, that is, information about a + promotion computed asynchronously. + version_number (int): + Optional. Represents the existing version (freshness) of the + promotion, which can be used to preserve the right order + when multiple updates are done at the same time. + + If set, the insertion is prevented when version number is + lower than the current version number of the existing + promotion. Re-insertion (for example, promotion refresh + after 30 days) can be performed with the current + ``version_number``. + + If the operation is prevented, the aborted exception will be + thrown. + + This field is a member of `oneof`_ ``_version_number``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + promotion_id: str = proto.Field( + proto.STRING, + number=2, + ) + content_language: str = proto.Field( + proto.STRING, + number=3, + ) + target_country: str = proto.Field( + proto.STRING, + number=4, + ) + redemption_channel: MutableSequence[promotions_common.RedemptionChannel] = proto.RepeatedField( + proto.ENUM, + number=5, + enum=promotions_common.RedemptionChannel, + ) + data_source: str = proto.Field( + proto.STRING, + number=6, + ) + attributes: promotions_common.Attributes = proto.Field( + proto.MESSAGE, + number=7, + message=promotions_common.Attributes, + ) + custom_attributes: MutableSequence[types.CustomAttribute] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message=types.CustomAttribute, + ) + promotion_status: promotions_common.PromotionStatus = proto.Field( + proto.MESSAGE, + number=9, + message=promotions_common.PromotionStatus, + ) + version_number: int = proto.Field( + proto.INT64, + number=10, + optional=True, + ) + + +class InsertPromotionRequest(proto.Message): + r"""Request message for the ``InsertPromotion`` method. + + Attributes: + parent (str): + Required. The account where the promotion + will be inserted. Format: accounts/{account} + promotion (google.shopping.merchant_promotions_v1beta.types.Promotion): + Required. The promotion to insert. + data_source (str): + Required. The data source of the + `promotion `__ + Format: ``accounts/{account}/dataSources/{datasource}``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + promotion: 'Promotion' = proto.Field( + proto.MESSAGE, + number=2, + message='Promotion', + ) + data_source: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GetPromotionRequest(proto.Message): + r"""Request message for the ``GetPromotion`` method. + + Attributes: + name (str): + Required. The name of the promotion to retrieve. Format: + ``accounts/{account}/promotions/{promotions}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListPromotionsRequest(proto.Message): + r"""Request message for the ``ListPromotions`` method. + + Attributes: + parent (str): + Required. The account to list processed promotions for. + Format: ``accounts/{account}`` + page_size (int): + Output only. The maximum number of promotions + to return. The service may return fewer than + this value. The maximum value is 1000; values + above 1000 will be coerced to 1000. If + unspecified, the maximum number of promotions + will be returned. + page_token (str): + Output only. A page token, received from a previous + ``ListPromotions`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListPromotions`` must match the call that provided the + page token. + """ + + 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 ListPromotionsResponse(proto.Message): + r"""Response message for the ``ListPromotions`` method. + + Attributes: + promotions (MutableSequence[google.shopping.merchant_promotions_v1beta.types.Promotion]): + The processed promotions from the specified + account. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + promotions: MutableSequence['Promotion'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Promotion', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions_common.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions_common.py new file mode 100644 index 000000000000..290e4bcf4ee5 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions_common.py @@ -0,0 +1,671 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.shopping.type.types import types +from google.type import interval_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.shopping.merchant.promotions.v1beta', + manifest={ + 'ProductApplicability', + 'StoreApplicability', + 'OfferType', + 'RedemptionChannel', + 'CouponValueType', + 'Attributes', + 'PromotionStatus', + }, +) + + +class ProductApplicability(proto.Enum): + r"""Which product or list of products the promotion applies to. + + Values: + PRODUCT_APPLICABILITY_UNSPECIFIED (0): + Which products the promotion applies to is + unknown. + ALL_PRODUCTS (1): + Applicable to all products. + SPECIFIC_PRODUCTS (2): + Applicable to only a single product or list + of products. + """ + PRODUCT_APPLICABILITY_UNSPECIFIED = 0 + ALL_PRODUCTS = 1 + SPECIFIC_PRODUCTS = 2 + + +class StoreApplicability(proto.Enum): + r"""Store codes or list of store codes the promotion applies to. + Only for Local inventory ads promotions. + + Values: + STORE_APPLICABILITY_UNSPECIFIED (0): + Which store codes the promotion applies to is + unknown. + ALL_STORES (1): + Promotion applies to all stores. + SPECIFIC_STORES (2): + Promotion applies to only the specified + stores. + """ + STORE_APPLICABILITY_UNSPECIFIED = 0 + ALL_STORES = 1 + SPECIFIC_STORES = 2 + + +class OfferType(proto.Enum): + r"""Offer type of a promotion. + + Values: + OFFER_TYPE_UNSPECIFIED (0): + Unknown offer type. + NO_CODE (1): + Offer type without a code. + GENERIC_CODE (2): + Offer type with a code. Generic redemption code for the + promotion is required when ``offerType`` = ``GENERIC_CODE``. + """ + OFFER_TYPE_UNSPECIFIED = 0 + NO_CODE = 1 + GENERIC_CODE = 2 + + +class RedemptionChannel(proto.Enum): + r"""Channel of a promotion. + + Values: + REDEMPTION_CHANNEL_UNSPECIFIED (0): + Indicates that the channel is unspecified. + IN_STORE (1): + Indicates that the channel is in store. This is same as + ``local`` channel used for ``products``. + ONLINE (2): + Indicates that the channel is online. + """ + REDEMPTION_CHANNEL_UNSPECIFIED = 0 + IN_STORE = 1 + ONLINE = 2 + + +class CouponValueType(proto.Enum): + r"""`Coupon value + type `__ + of a promotion. + + Values: + COUPON_VALUE_TYPE_UNSPECIFIED (0): + Indicates that the coupon value type is + unspecified. + MONEY_OFF (1): + Money off coupon value type. + PERCENT_OFF (2): + Percent off coupon value type. + BUY_M_GET_N_MONEY_OFF (3): + Buy M quantity, get N money off coupon value type. + ``minimum_purchase_quantity`` and + ``get_this_quantity_discounted`` must be present. + ``money_off_amount`` must also be present. + BUY_M_GET_N_PERCENT_OFF (4): + Buy M quantity, get N percent off coupon value type. + ``minimum_purchase_quantity`` and + ``get_this_quantity_discounted`` must be present. + ``percent_off_percentage`` must also be present. + BUY_M_GET_MONEY_OFF (5): + Buy M quantity, get money off. ``minimum_purchase_quantity`` + and ``money_off_amount`` must be present. + BUY_M_GET_PERCENT_OFF (6): + Buy M quantity, get money off. ``minimum_purchase_quantity`` + and ``percent_off_percentage`` must be present. + FREE_GIFT (7): + Free gift with description only. + FREE_GIFT_WITH_VALUE (8): + Free gift with monetary value. + FREE_GIFT_WITH_ITEM_ID (9): + Free gift with item ID. + FREE_SHIPPING_STANDARD (10): + Standard free shipping coupon value type. + FREE_SHIPPING_OVERNIGHT (11): + Overnight free shipping coupon value type. + FREE_SHIPPING_TWO_DAY (12): + Two day free shipping coupon value type. + """ + COUPON_VALUE_TYPE_UNSPECIFIED = 0 + MONEY_OFF = 1 + PERCENT_OFF = 2 + BUY_M_GET_N_MONEY_OFF = 3 + BUY_M_GET_N_PERCENT_OFF = 4 + BUY_M_GET_MONEY_OFF = 5 + BUY_M_GET_PERCENT_OFF = 6 + FREE_GIFT = 7 + FREE_GIFT_WITH_VALUE = 8 + FREE_GIFT_WITH_ITEM_ID = 9 + FREE_SHIPPING_STANDARD = 10 + FREE_SHIPPING_OVERNIGHT = 11 + FREE_SHIPPING_TWO_DAY = 12 + + +class Attributes(proto.Message): + r"""Attributes. + + Attributes: + product_applicability (google.shopping.merchant_promotions_v1beta.types.ProductApplicability): + Required. Applicability of the promotion to either all + products or `only specific + products `__. + offer_type (google.shopping.merchant_promotions_v1beta.types.OfferType): + Required. + `Type `__ + of the promotion. Use this attribute to indicate whether or + not customers need a coupon code to redeem your promotion. + generic_redemption_code (str): + Optional. Generic redemption code for the promotion. To be + used with the ``offerType`` field and must meet the `minimum + requirements `__. + long_title (str): + Required. `Long + title `__ + for the promotion. + coupon_value_type (google.shopping.merchant_promotions_v1beta.types.CouponValueType): + Required. The [coupon value type] + (https://support.google.com/merchants/answer/13861986?ref_topic=13773355&sjid=17642868584668136159-NC) + attribute to signal the type of promotion that you are + running. Depending on type of the selected coupon value + `some attributes are + required `__. + promotion_destinations (MutableSequence[google.shopping.type.types.Destination.DestinationEnum]): + Required. The list of destinations where the promotion + applies to. If you don't specify a destination by including + a supported value in your data source, your promotion will + display in Shopping ads and free listings by default. + + You may have previously submitted the following values as + destinations for your products: Shopping Actions, Surfaces + across Google, Local surfaces across Google. To represent + these values use ``FREE_LISTINGS``, ``FREE_LOCAL_LISTINGS``, + ``LOCAL_INVENTORY_ADS``. For more details see `Promotion + destination `__ + item_id_inclusion (MutableSequence[str]): + Optional. Product filter by `item + ID `__ + for the promotion. The product filter attributes only + applies when the products eligible for promotion product + applicability ``product_applicability`` attribute is set to + `specific_products `__. + brand_inclusion (MutableSequence[str]): + Optional. Product filter by brand for the promotion. The + product filter attributes only applies when the products + eligible for promotion product applicability + ``product_applicability`` attribute is set to + `specific_products `__. + item_group_id_inclusion (MutableSequence[str]): + Optional. Product filter by item group ID for the promotion. + The product filter attributes only applies when the products + eligible for promotion product applicability + [product_applicability] attribute is set to + `specific_products `__. + product_type_inclusion (MutableSequence[str]): + Optional. Product filter by product type for the promotion. + The product filter attributes only applies when the products + eligible for promotion product applicability + ``product_applicability`` attribute is set to + `specific_products `__. + item_id_exclusion (MutableSequence[str]): + Optional. Product filter by `item ID + exclusion `__ + for the promotion. The product filter attributes only + applies when the products eligible for promotion product + applicability ``product_applicability`` attribute is set to + `specific_products `__. + brand_exclusion (MutableSequence[str]): + Optional. Product filter by `brand + exclusion `__ + for the promotion. The product filter attributes only + applies when the products eligible for promotion product + applicability ``product_applicability`` attribute is set to + `specific_products `__. + item_group_id_exclusion (MutableSequence[str]): + Optional. Product filter by `item group + ID `__. + The product filter attributes only applies when the products + eligible for promotion product applicability + ``product_applicability`` attribute is set to + `specific_products `__. + exclusion for the promotion. + product_type_exclusion (MutableSequence[str]): + Optional. Product filter by `product type + exclusion `__ + for the promotion. The product filter attributes only + applies when the products eligible for promotion product + applicability ``product_applicability`` attribute is set to + `specific_products `__. + minimum_purchase_amount (google.shopping.type.types.Price): + Optional. `Minimum purchase + amount `__ + for the promotion. + minimum_purchase_quantity (int): + Optional. `Minimum purchase + quantity `__ + for the promotion. + limit_quantity (int): + Optional. `Maximum purchase + quantity `__ + for the promotion. + limit_value (google.shopping.type.types.Price): + Optional. `Maximum product + price `__ + for promotion. + percent_off (int): + Optional. The `percentage + discount `__ + offered in the promotion. + money_off_amount (google.shopping.type.types.Price): + Optional. The `money off + amount `__ + offered in the promotion. + get_this_quantity_discounted (int): + Optional. The number of items discounted in the promotion. + The attribute is set when ``couponValueType`` is equal to + ``buy_m_get_n_money_off`` or ``buy_m_get_n_percent_off``. + free_gift_value (google.shopping.type.types.Price): + Optional. `Free gift + value `__ + for the promotion. + free_gift_description (str): + Optional. `Free gift + description `__ + for the promotion. + free_gift_item_id (str): + Optional. `Free gift item + ID `__ + for the promotion. + promotion_effective_time_period (google.type.interval_pb2.Interval): + Required. ``TimePeriod`` representation of the promotion's + effective dates. This attribute specifies that the promotion + can be tested on your online store during this time period. + promotion_display_time_period (google.type.interval_pb2.Interval): + Optional. ``TimePeriod`` representation of the promotion's + display dates. This attribute specifies the date and time + frame when the promotion will be live on Google.com and + Shopping ads. If the display time period for promotion + ``promotion_display_time_period`` attribute is not + specified, the promotion effective time period + ``promotion_effective_time_period`` determines the date and + time frame when the promotion will be live on Google.com and + Shopping ads. + store_applicability (google.shopping.merchant_promotions_v1beta.types.StoreApplicability): + Optional. Whether the promotion applies to `all stores, or + only specified + stores `__. + Local Inventory ads promotions throw an error if no store + applicability is included. An ``INVALID_ARGUMENT`` error is + thrown if ``store_applicability`` is set to ``ALL_STORES`` + and ``store_codes_inclusion`` or ``score_code_exclusion`` is + set to a value. + store_codes_inclusion (MutableSequence[str]): + Optional. `Store codes to + include `__ + for the promotion. The store filter attributes only applies + when the ``store_applicability`` attribute is set to + `specific_stores `__. + + Store code (the store ID from your Business Profile) of the + physical store the product is sold in. See the `Local + product inventory data + specification `__ + for more information. + store_codes_exclusion (MutableSequence[str]): + Optional. `Store codes to + exclude `__ + for the promotion. The store filter attributes only applies + when the ``store_applicability`` attribute is set to + `specific_stores `__. + promotion_url (str): + Optional. URL to the page on the merchant's site where the + promotion shows. Local Inventory ads promotions throw an + error if no ``promotion_url`` is included. URL is used to + confirm that the promotion is valid and can be redeemed. + """ + + product_applicability: 'ProductApplicability' = proto.Field( + proto.ENUM, + number=1, + enum='ProductApplicability', + ) + offer_type: 'OfferType' = proto.Field( + proto.ENUM, + number=2, + enum='OfferType', + ) + generic_redemption_code: str = proto.Field( + proto.STRING, + number=3, + ) + long_title: str = proto.Field( + proto.STRING, + number=4, + ) + coupon_value_type: 'CouponValueType' = proto.Field( + proto.ENUM, + number=5, + enum='CouponValueType', + ) + promotion_destinations: MutableSequence[types.Destination.DestinationEnum] = proto.RepeatedField( + proto.ENUM, + number=6, + enum=types.Destination.DestinationEnum, + ) + item_id_inclusion: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + brand_inclusion: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) + item_group_id_inclusion: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + product_type_inclusion: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=10, + ) + item_id_exclusion: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=11, + ) + brand_exclusion: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=12, + ) + item_group_id_exclusion: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=13, + ) + product_type_exclusion: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=14, + ) + minimum_purchase_amount: types.Price = proto.Field( + proto.MESSAGE, + number=15, + message=types.Price, + ) + minimum_purchase_quantity: int = proto.Field( + proto.INT64, + number=16, + ) + limit_quantity: int = proto.Field( + proto.INT64, + number=17, + ) + limit_value: types.Price = proto.Field( + proto.MESSAGE, + number=18, + message=types.Price, + ) + percent_off: int = proto.Field( + proto.INT64, + number=19, + ) + money_off_amount: types.Price = proto.Field( + proto.MESSAGE, + number=20, + message=types.Price, + ) + get_this_quantity_discounted: int = proto.Field( + proto.INT64, + number=21, + ) + free_gift_value: types.Price = proto.Field( + proto.MESSAGE, + number=22, + message=types.Price, + ) + free_gift_description: str = proto.Field( + proto.STRING, + number=23, + ) + free_gift_item_id: str = proto.Field( + proto.STRING, + number=24, + ) + promotion_effective_time_period: interval_pb2.Interval = proto.Field( + proto.MESSAGE, + number=25, + message=interval_pb2.Interval, + ) + promotion_display_time_period: interval_pb2.Interval = proto.Field( + proto.MESSAGE, + number=26, + message=interval_pb2.Interval, + ) + store_applicability: 'StoreApplicability' = proto.Field( + proto.ENUM, + number=28, + enum='StoreApplicability', + ) + store_codes_inclusion: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=29, + ) + store_codes_exclusion: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=30, + ) + promotion_url: str = proto.Field( + proto.STRING, + number=31, + ) + + +class PromotionStatus(proto.Message): + r"""The status of the promotion. + + Attributes: + destination_statuses (MutableSequence[google.shopping.merchant_promotions_v1beta.types.PromotionStatus.DestinationStatus]): + Output only. The intended destinations for + the promotion. + item_level_issues (MutableSequence[google.shopping.merchant_promotions_v1beta.types.PromotionStatus.ItemLevelIssue]): + Output only. A list of issues associated with + the promotion. + creation_date (google.protobuf.timestamp_pb2.Timestamp): + Output only. Date on which the promotion has been created in + `ISO 8601 `__ format: + Date, time, and offset, for example + ``2020-01-02T09:00:00+01:00`` or ``2020-01-02T09:00:00Z`` + last_update_date (google.protobuf.timestamp_pb2.Timestamp): + Output only. Date on which the promotion status has been + last updated in `ISO + 8601 `__ format: + Date, time, and offset, for example + ``2020-01-02T09:00:00+01:00`` or ``2020-01-02T09:00:00Z`` + """ + + class DestinationStatus(proto.Message): + r"""The status for the specified destination. + + Attributes: + reporting_context (google.shopping.type.types.ReportingContext.ReportingContextEnum): + Output only. The name of the promotion + destination. + status (google.shopping.merchant_promotions_v1beta.types.PromotionStatus.DestinationStatus.State): + Output only. The status for the specified + destination. + """ + class State(proto.Enum): + r"""The current state of the promotion. + + Values: + STATE_UNSPECIFIED (0): + Unknown promotion state. + IN_REVIEW (1): + The promotion is under review. + REJECTED (2): + The promotion is disapproved. + LIVE (3): + The promotion is approved and active. + STOPPED (4): + The promotion is stopped by merchant. + EXPIRED (5): + The promotion is no longer active. + PENDING (6): + The promotion is not stopped, and all reviews + are approved, but the active date is in the + future. + """ + STATE_UNSPECIFIED = 0 + IN_REVIEW = 1 + REJECTED = 2 + LIVE = 3 + STOPPED = 4 + EXPIRED = 5 + PENDING = 6 + + reporting_context: types.ReportingContext.ReportingContextEnum = proto.Field( + proto.ENUM, + number=1, + enum=types.ReportingContext.ReportingContextEnum, + ) + status: 'PromotionStatus.DestinationStatus.State' = proto.Field( + proto.ENUM, + number=2, + enum='PromotionStatus.DestinationStatus.State', + ) + + class ItemLevelIssue(proto.Message): + r"""The issue associated with the promotion. + + Attributes: + code (str): + Output only. The error code of the issue. + severity (google.shopping.merchant_promotions_v1beta.types.PromotionStatus.ItemLevelIssue.Severity): + Output only. How this issue affects serving + of the promotion. + resolution (str): + Output only. Whether the issue can be + resolved by the merchant. + attribute (str): + Output only. The attribute's name, if the + issue is caused by a single attribute. + reporting_context (google.shopping.type.types.ReportingContext.ReportingContextEnum): + Output only. The destination the issue + applies to. + description (str): + Output only. A short issue description in + English. + detail (str): + Output only. A detailed issue description in + English. + documentation (str): + Output only. The URL of a web page to help + with resolving this issue. + applicable_countries (MutableSequence[str]): + Output only. List of country codes (ISO + 3166-1 alpha-2) where issue applies to the + offer. + """ + class Severity(proto.Enum): + r"""The severity of the issue. + + Values: + SEVERITY_UNSPECIFIED (0): + Not specified. + NOT_IMPACTED (1): + This issue represents a warning and does not + have a direct affect on the promotion. + DEMOTED (2): + The promotion is demoted and most likely have + limited performance in search results + DISAPPROVED (3): + Issue disapproves the promotion. + """ + SEVERITY_UNSPECIFIED = 0 + NOT_IMPACTED = 1 + DEMOTED = 2 + DISAPPROVED = 3 + + code: str = proto.Field( + proto.STRING, + number=1, + ) + severity: 'PromotionStatus.ItemLevelIssue.Severity' = proto.Field( + proto.ENUM, + number=2, + enum='PromotionStatus.ItemLevelIssue.Severity', + ) + resolution: str = proto.Field( + proto.STRING, + number=3, + ) + attribute: str = proto.Field( + proto.STRING, + number=4, + ) + reporting_context: types.ReportingContext.ReportingContextEnum = proto.Field( + proto.ENUM, + number=5, + enum=types.ReportingContext.ReportingContextEnum, + ) + description: str = proto.Field( + proto.STRING, + number=6, + ) + detail: str = proto.Field( + proto.STRING, + number=7, + ) + documentation: str = proto.Field( + proto.STRING, + number=8, + ) + applicable_countries: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + + destination_statuses: MutableSequence[DestinationStatus] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=DestinationStatus, + ) + item_level_issues: MutableSequence[ItemLevelIssue] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=ItemLevelIssue, + ) + creation_date: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + last_update_date: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/mypy.ini b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/mypy.ini new file mode 100644 index 000000000000..574c5aed394b --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/noxfile.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/noxfile.py new file mode 100644 index 000000000000..3cd901f36b88 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/noxfile.py @@ -0,0 +1,280 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 re +import shutil +import subprocess +import sys + + +import nox # type: ignore + +ALL_PYTHON = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", +] + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = 'google-shopping-merchant-promotions' + +BLACK_VERSION = "black==22.3.0" +BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] +DEFAULT_PYTHON_VERSION = "3.13" + +nox.sessions = [ + "unit", + "cover", + "mypy", + "check_lower_bounds" + # exclude update_lower_bounds from default + "docs", + "blacken", + "lint", + "prerelease_deps", +] + +@nox.session(python=ALL_PYTHON) +@nox.parametrize( + "protobuf_implementation", + [ "python", "upb", "cpp" ], +) +def unit(session, protobuf_implementation): + """Run the unit test suite.""" + + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + session.skip("cpp implementation is not supported in python 3.11+") + + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + session.install('-e', '.', "-c", f"testing/constraints-{session.python}.txt") + + # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. + # The 'cpp' implementation requires Protobuf<4. + if protobuf_implementation == "cpp": + session.install("protobuf<4") + + session.run( + 'py.test', + '--quiet', + '--cov=google/shopping/merchant_promotions_v1beta/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)), + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + +@nox.session(python=ALL_PYTHON[-1]) +@nox.parametrize( + "protobuf_implementation", + [ "python", "upb", "cpp" ], +) +def prerelease_deps(session, protobuf_implementation): + """Run the unit test suite against pre-release versions of dependencies.""" + + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + session.skip("cpp implementation is not supported in python 3.11+") + + # Install test environment dependencies + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + + # Install the package without dependencies + session.install('-e', '.', '--no-deps') + + # We test the minimum dependency versions using the minimum Python + # version so the lowest python runtime that we test has a corresponding constraints + # file, located at `testing/constraints--.txt`, which contains all of the + # dependencies and extras. + with open( + CURRENT_DIRECTORY + / "testing" + / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + session.install(*constraints_deps) + + prerel_deps = [ + "googleapis-common-protos", + "google-api-core", + "google-auth", + # Exclude grpcio!=1.67.0rc1 which does not support python 3.13 + "grpcio!=1.67.0rc1", + "grpcio-status", + "protobuf", + "proto-plus", + ] + + for dep in prerel_deps: + session.install("--pre", "--no-deps", "--upgrade", dep) + + # Remaining dependencies + other_deps = [ + "requests", + ] + session.install(*other_deps) + + # Print out prerelease package versions + + session.run("python", "-c", "import google.api_core; print(google.api_core.__version__)") + session.run("python", "-c", "import google.auth; print(google.auth.__version__)") + session.run("python", "-c", "import grpc; print(grpc.__version__)") + session.run( + "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" + ) + session.run( + "python", "-c", "import proto; print(proto.__version__)" + ) + + session.run( + 'py.test', + '--quiet', + '--cov=google/shopping/merchant_promotions_v1beta/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)), + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +@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', + '-p', + '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, + ) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_async.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_async.py new file mode 100644 index 000000000000..66bd0db4ca0d --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetPromotion +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-shopping-merchant-promotions + + +# [START merchantapi_v1beta_generated_PromotionsService_GetPromotion_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.shopping import merchant_promotions_v1beta + + +async def sample_get_promotion(): + # Create a client + client = merchant_promotions_v1beta.PromotionsServiceAsyncClient() + + # Initialize request argument(s) + request = merchant_promotions_v1beta.GetPromotionRequest( + name="name_value", + ) + + # Make the request + response = await client.get_promotion(request=request) + + # Handle the response + print(response) + +# [END merchantapi_v1beta_generated_PromotionsService_GetPromotion_async] diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_sync.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_sync.py new file mode 100644 index 000000000000..6b8e9dade3e9 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetPromotion +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-shopping-merchant-promotions + + +# [START merchantapi_v1beta_generated_PromotionsService_GetPromotion_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.shopping import merchant_promotions_v1beta + + +def sample_get_promotion(): + # Create a client + client = merchant_promotions_v1beta.PromotionsServiceClient() + + # Initialize request argument(s) + request = merchant_promotions_v1beta.GetPromotionRequest( + name="name_value", + ) + + # Make the request + response = client.get_promotion(request=request) + + # Handle the response + print(response) + +# [END merchantapi_v1beta_generated_PromotionsService_GetPromotion_sync] diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_async.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_async.py new file mode 100644 index 000000000000..d9245ecabde7 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_async.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for InsertPromotion +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-shopping-merchant-promotions + + +# [START merchantapi_v1beta_generated_PromotionsService_InsertPromotion_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.shopping import merchant_promotions_v1beta + + +async def sample_insert_promotion(): + # Create a client + client = merchant_promotions_v1beta.PromotionsServiceAsyncClient() + + # Initialize request argument(s) + promotion = merchant_promotions_v1beta.Promotion() + promotion.promotion_id = "promotion_id_value" + promotion.content_language = "content_language_value" + promotion.target_country = "target_country_value" + promotion.redemption_channel = ['ONLINE'] + + request = merchant_promotions_v1beta.InsertPromotionRequest( + parent="parent_value", + promotion=promotion, + data_source="data_source_value", + ) + + # Make the request + response = await client.insert_promotion(request=request) + + # Handle the response + print(response) + +# [END merchantapi_v1beta_generated_PromotionsService_InsertPromotion_async] diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_sync.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_sync.py new file mode 100644 index 000000000000..2fd44913b58c --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_sync.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for InsertPromotion +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-shopping-merchant-promotions + + +# [START merchantapi_v1beta_generated_PromotionsService_InsertPromotion_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.shopping import merchant_promotions_v1beta + + +def sample_insert_promotion(): + # Create a client + client = merchant_promotions_v1beta.PromotionsServiceClient() + + # Initialize request argument(s) + promotion = merchant_promotions_v1beta.Promotion() + promotion.promotion_id = "promotion_id_value" + promotion.content_language = "content_language_value" + promotion.target_country = "target_country_value" + promotion.redemption_channel = ['ONLINE'] + + request = merchant_promotions_v1beta.InsertPromotionRequest( + parent="parent_value", + promotion=promotion, + data_source="data_source_value", + ) + + # Make the request + response = client.insert_promotion(request=request) + + # Handle the response + print(response) + +# [END merchantapi_v1beta_generated_PromotionsService_InsertPromotion_sync] diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_async.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_async.py new file mode 100644 index 000000000000..ae88a1355d74 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListPromotions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-shopping-merchant-promotions + + +# [START merchantapi_v1beta_generated_PromotionsService_ListPromotions_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.shopping import merchant_promotions_v1beta + + +async def sample_list_promotions(): + # Create a client + client = merchant_promotions_v1beta.PromotionsServiceAsyncClient() + + # Initialize request argument(s) + request = merchant_promotions_v1beta.ListPromotionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_promotions(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END merchantapi_v1beta_generated_PromotionsService_ListPromotions_async] diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_sync.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_sync.py new file mode 100644 index 000000000000..d2d3f2a247df --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListPromotions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-shopping-merchant-promotions + + +# [START merchantapi_v1beta_generated_PromotionsService_ListPromotions_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.shopping import merchant_promotions_v1beta + + +def sample_list_promotions(): + # Create a client + client = merchant_promotions_v1beta.PromotionsServiceClient() + + # Initialize request argument(s) + request = merchant_promotions_v1beta.ListPromotionsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_promotions(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END merchantapi_v1beta_generated_PromotionsService_ListPromotions_sync] diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1beta.json b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1beta.json new file mode 100644 index 000000000000..4b7f108a5403 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1beta.json @@ -0,0 +1,490 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.shopping.merchant.promotions.v1beta", + "version": "v1beta" + } + ], + "language": "PYTHON", + "name": "google-shopping-merchant-promotions", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceAsyncClient", + "shortName": "PromotionsServiceAsyncClient" + }, + "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceAsyncClient.get_promotion", + "method": { + "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService.GetPromotion", + "service": { + "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "shortName": "PromotionsService" + }, + "shortName": "GetPromotion" + }, + "parameters": [ + { + "name": "request", + "type": "google.shopping.merchant_promotions_v1beta.types.GetPromotionRequest" + }, + { + "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.shopping.merchant_promotions_v1beta.types.Promotion", + "shortName": "get_promotion" + }, + "description": "Sample for GetPromotion", + "file": "merchantapi_v1beta_generated_promotions_service_get_promotion_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "merchantapi_v1beta_generated_PromotionsService_GetPromotion_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": "merchantapi_v1beta_generated_promotions_service_get_promotion_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceClient", + "shortName": "PromotionsServiceClient" + }, + "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceClient.get_promotion", + "method": { + "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService.GetPromotion", + "service": { + "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "shortName": "PromotionsService" + }, + "shortName": "GetPromotion" + }, + "parameters": [ + { + "name": "request", + "type": "google.shopping.merchant_promotions_v1beta.types.GetPromotionRequest" + }, + { + "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.shopping.merchant_promotions_v1beta.types.Promotion", + "shortName": "get_promotion" + }, + "description": "Sample for GetPromotion", + "file": "merchantapi_v1beta_generated_promotions_service_get_promotion_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "merchantapi_v1beta_generated_PromotionsService_GetPromotion_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": "merchantapi_v1beta_generated_promotions_service_get_promotion_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceAsyncClient", + "shortName": "PromotionsServiceAsyncClient" + }, + "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceAsyncClient.insert_promotion", + "method": { + "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService.InsertPromotion", + "service": { + "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "shortName": "PromotionsService" + }, + "shortName": "InsertPromotion" + }, + "parameters": [ + { + "name": "request", + "type": "google.shopping.merchant_promotions_v1beta.types.InsertPromotionRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.shopping.merchant_promotions_v1beta.types.Promotion", + "shortName": "insert_promotion" + }, + "description": "Sample for InsertPromotion", + "file": "merchantapi_v1beta_generated_promotions_service_insert_promotion_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "merchantapi_v1beta_generated_PromotionsService_InsertPromotion_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": "merchantapi_v1beta_generated_promotions_service_insert_promotion_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceClient", + "shortName": "PromotionsServiceClient" + }, + "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceClient.insert_promotion", + "method": { + "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService.InsertPromotion", + "service": { + "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "shortName": "PromotionsService" + }, + "shortName": "InsertPromotion" + }, + "parameters": [ + { + "name": "request", + "type": "google.shopping.merchant_promotions_v1beta.types.InsertPromotionRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.shopping.merchant_promotions_v1beta.types.Promotion", + "shortName": "insert_promotion" + }, + "description": "Sample for InsertPromotion", + "file": "merchantapi_v1beta_generated_promotions_service_insert_promotion_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "merchantapi_v1beta_generated_PromotionsService_InsertPromotion_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": "merchantapi_v1beta_generated_promotions_service_insert_promotion_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceAsyncClient", + "shortName": "PromotionsServiceAsyncClient" + }, + "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceAsyncClient.list_promotions", + "method": { + "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService.ListPromotions", + "service": { + "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "shortName": "PromotionsService" + }, + "shortName": "ListPromotions" + }, + "parameters": [ + { + "name": "request", + "type": "google.shopping.merchant_promotions_v1beta.types.ListPromotionsRequest" + }, + { + "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.shopping.merchant_promotions_v1beta.services.promotions_service.pagers.ListPromotionsAsyncPager", + "shortName": "list_promotions" + }, + "description": "Sample for ListPromotions", + "file": "merchantapi_v1beta_generated_promotions_service_list_promotions_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "merchantapi_v1beta_generated_PromotionsService_ListPromotions_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": "merchantapi_v1beta_generated_promotions_service_list_promotions_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceClient", + "shortName": "PromotionsServiceClient" + }, + "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceClient.list_promotions", + "method": { + "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService.ListPromotions", + "service": { + "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService", + "shortName": "PromotionsService" + }, + "shortName": "ListPromotions" + }, + "parameters": [ + { + "name": "request", + "type": "google.shopping.merchant_promotions_v1beta.types.ListPromotionsRequest" + }, + { + "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.shopping.merchant_promotions_v1beta.services.promotions_service.pagers.ListPromotionsPager", + "shortName": "list_promotions" + }, + "description": "Sample for ListPromotions", + "file": "merchantapi_v1beta_generated_promotions_service_list_promotions_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "merchantapi_v1beta_generated_PromotionsService_ListPromotions_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": "merchantapi_v1beta_generated_promotions_service_list_promotions_sync.py" + } + ] +} diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/scripts/fixup_merchant_promotions_v1beta_keywords.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/scripts/fixup_merchant_promotions_v1beta_keywords.py new file mode 100644 index 000000000000..398615e0afb5 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/scripts/fixup_merchant_promotions_v1beta_keywords.py @@ -0,0 +1,178 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 merchant_promotionsCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'get_promotion': ('name', ), + 'insert_promotion': ('parent', 'promotion', 'data_source', ), + 'list_promotions': ('parent', 'page_size', 'page_token', ), + } + + 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=merchant_promotionsCallTransformer(), +): + """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 merchant_promotions 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/google-shopping-merchant-promotions/v1beta/setup.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/setup.py new file mode 100644 index 000000000000..a4ef40e7ce4a --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/setup.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 re + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = 'google-shopping-merchant-promotions' + + +description = "Google Shopping Merchant Promotions API client library" + +version = None + +with open(os.path.join(package_root, 'google/shopping/merchant_promotions/gapic_version.py')) as fp: + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + assert (len(version_candidates) == 1) + version = version_candidates[0] + +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.1, <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.*", + # Exclude incompatible versions of `google-auth` + # See https://github.com/googleapis/google-cloud-python/issues/12364 + "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", + "proto-plus >= 1.22.3, <2.0.0dev", + "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", + "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", + "google-shopping-type >= 0.1.6, <1.0.0dev", +] +extras = { +} +url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-promotions" + +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.find_namespace_packages() + if package.startswith("google") +] + +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", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + install_requires=dependencies, + extras_require=extras, + include_package_data=True, + zip_safe=False, +) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.10.txt b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.10.txt new file mode 100644 index 000000000000..4cae520d02b2 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.10.txt @@ -0,0 +1,7 @@ +# -*- 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 +google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.11.txt b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.11.txt new file mode 100644 index 000000000000..4cae520d02b2 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.11.txt @@ -0,0 +1,7 @@ +# -*- 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 +google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.12.txt b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.12.txt new file mode 100644 index 000000000000..4cae520d02b2 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.12.txt @@ -0,0 +1,7 @@ +# -*- 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 +google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.13.txt b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.13.txt new file mode 100644 index 000000000000..4cae520d02b2 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.13.txt @@ -0,0 +1,7 @@ +# -*- 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 +google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.7.txt b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.7.txt new file mode 100644 index 000000000000..130a0c0f80ab --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.7.txt @@ -0,0 +1,11 @@ +# 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.1 +google-auth==2.14.1 +proto-plus==1.22.3 +protobuf==3.20.2 +google-shopping-type==0.1.6 diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.8.txt b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.8.txt new file mode 100644 index 000000000000..4cae520d02b2 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.8.txt @@ -0,0 +1,7 @@ +# -*- 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 +google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.9.txt b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.9.txt new file mode 100644 index 000000000000..4cae520d02b2 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.9.txt @@ -0,0 +1,7 @@ +# -*- 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 +google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-promotions/v1beta/tests/unit/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py new file mode 100644 index 000000000000..0d1f98a800e1 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py @@ -0,0 +1,3661 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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, AsyncIterable +from google.protobuf import json_format +import json +import math +import pytest +from google.api_core import api_core_version +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 + +try: + from google.auth.aio import credentials as ga_credentials_async + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +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.api_core import retry as retries +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.protobuf import timestamp_pb2 # type: ignore +from google.shopping.merchant_promotions_v1beta.services.promotions_service import PromotionsServiceAsyncClient +from google.shopping.merchant_promotions_v1beta.services.promotions_service import PromotionsServiceClient +from google.shopping.merchant_promotions_v1beta.services.promotions_service import pagers +from google.shopping.merchant_promotions_v1beta.services.promotions_service import transports +from google.shopping.merchant_promotions_v1beta.types import promotions +from google.shopping.merchant_promotions_v1beta.types import promotions_common +from google.shopping.type.types import types +from google.type import interval_pb2 # type: ignore +import google.auth + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + +# 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 + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return "test.{UNIVERSE_DOMAIN}" if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) else client._DEFAULT_ENDPOINT_TEMPLATE + + +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 PromotionsServiceClient._get_default_mtls_endpoint(None) is None + assert PromotionsServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert PromotionsServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert PromotionsServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert PromotionsServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert PromotionsServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + +def test__read_environment_variables(): + assert PromotionsServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert PromotionsServiceClient._read_environment_variables() == (True, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert PromotionsServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError) as excinfo: + PromotionsServiceClient._read_environment_variables() + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert PromotionsServiceClient._read_environment_variables() == (False, "never", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert PromotionsServiceClient._read_environment_variables() == (False, "always", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert PromotionsServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + PromotionsServiceClient._read_environment_variables() + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert PromotionsServiceClient._read_environment_variables() == (False, "auto", "foo.com") + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert PromotionsServiceClient._get_client_cert_source(None, False) is None + assert PromotionsServiceClient._get_client_cert_source(mock_provided_cert_source, False) is None + assert PromotionsServiceClient._get_client_cert_source(mock_provided_cert_source, True) == mock_provided_cert_source + + 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_default_cert_source): + assert PromotionsServiceClient._get_client_cert_source(None, True) is mock_default_cert_source + assert PromotionsServiceClient._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source + +@mock.patch.object(PromotionsServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceClient)) +@mock.patch.object(PromotionsServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceAsyncClient)) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = PromotionsServiceClient._DEFAULT_UNIVERSE + default_endpoint = PromotionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) + mock_universe = "bar.com" + mock_endpoint = PromotionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) + + assert PromotionsServiceClient._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override + assert PromotionsServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == PromotionsServiceClient.DEFAULT_MTLS_ENDPOINT + assert PromotionsServiceClient._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint + assert PromotionsServiceClient._get_api_endpoint(None, None, default_universe, "always") == PromotionsServiceClient.DEFAULT_MTLS_ENDPOINT + assert PromotionsServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == PromotionsServiceClient.DEFAULT_MTLS_ENDPOINT + assert PromotionsServiceClient._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint + assert PromotionsServiceClient._get_api_endpoint(None, None, default_universe, "never") == default_endpoint + + with pytest.raises(MutualTLSChannelError) as excinfo: + PromotionsServiceClient._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto") + assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com." + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert PromotionsServiceClient._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain + assert PromotionsServiceClient._get_universe_domain(None, universe_domain_env) == universe_domain_env + assert PromotionsServiceClient._get_universe_domain(None, None) == PromotionsServiceClient._DEFAULT_UNIVERSE + + with pytest.raises(ValueError) as excinfo: + PromotionsServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc"), + (PromotionsServiceClient, transports.PromotionsServiceRestTransport, "rest"), +]) +def test__validate_universe_domain(client_class, transport_class, transport_name): + client = client_class( + transport=transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + ) + assert client._validate_universe_domain() == True + + # Test the case when universe is already validated. + assert client._validate_universe_domain() == True + + if transport_name == "grpc": + # Test the case where credentials are provided by the + # `local_channel_credentials`. The default universes in both match. + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + client = client_class(transport=transport_class(channel=channel)) + assert client._validate_universe_domain() == True + + # Test the case where credentials do not exist: e.g. a transport is provided + # with no credentials. Validation should still succeed because there is no + # mismatch with non-existent credentials. + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + transport=transport_class(channel=channel) + transport._credentials = None + client = client_class(transport=transport) + assert client._validate_universe_domain() == True + + # TODO: This is needed to cater for older versions of google-auth + # Make this test unconditional once the minimum supported version of + # google-auth becomes 2.23.0 or higher. + google_auth_major, google_auth_minor = [int(part) for part in google.auth.__version__.split(".")[0:2]] + if google_auth_major > 2 or (google_auth_major == 2 and google_auth_minor >= 23): + credentials = ga_credentials.AnonymousCredentials() + credentials._universe_domain = "foo.com" + # Test the case when there is a universe mismatch from the credentials. + client = client_class( + transport=transport_class(credentials=credentials) + ) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert str(excinfo.value) == "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (foo.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + + # Test the case when there is a universe mismatch from the client. + # + # TODO: Make this test unconditional once the minimum supported version of + # google-api-core becomes 2.15.0 or higher. + api_core_major, api_core_minor = [int(part) for part in api_core_version.__version__.split(".")[0:2]] + if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 15): + client = client_class(client_options={"universe_domain": "bar.com"}, transport=transport_class(credentials=ga_credentials.AnonymousCredentials(),)) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert str(excinfo.value) == "The configured universe domain (bar.com) does not match the universe domain found in the credentials (googleapis.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + + # Test that ValueError is raised if universe_domain is provided via client options and credentials is None + with pytest.raises(ValueError): + client._compare_universes("foo.bar", None) + + +@pytest.mark.parametrize("client_class,transport_name", [ + (PromotionsServiceClient, "grpc"), + (PromotionsServiceAsyncClient, "grpc_asyncio"), + (PromotionsServiceClient, "rest"), +]) +def test_promotions_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 == ( + 'merchantapi.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://merchantapi.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.PromotionsServiceGrpcTransport, "grpc"), + (transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.PromotionsServiceRestTransport, "rest"), +]) +def test_promotions_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", [ + (PromotionsServiceClient, "grpc"), + (PromotionsServiceAsyncClient, "grpc_asyncio"), + (PromotionsServiceClient, "rest"), +]) +def test_promotions_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 == ( + 'merchantapi.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://merchantapi.googleapis.com' + ) + + +def test_promotions_service_client_get_transport_class(): + transport = PromotionsServiceClient.get_transport_class() + available_transports = [ + transports.PromotionsServiceGrpcTransport, + transports.PromotionsServiceRestTransport, + ] + assert transport in available_transports + + transport = PromotionsServiceClient.get_transport_class("grpc") + assert transport == transports.PromotionsServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc"), + (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (PromotionsServiceClient, transports.PromotionsServiceRestTransport, "rest"), +]) +@mock.patch.object(PromotionsServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceClient)) +@mock.patch.object(PromotionsServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceAsyncClient)) +def test_promotions_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(PromotionsServiceClient, '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(PromotionsServiceClient, '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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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) as excinfo: + client = client_class(transport=transport_name) + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + # 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) as excinfo: + client = client_class(transport=transport_name) + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + + # 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + 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", [ + (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc", "true"), + (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc", "false"), + (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (PromotionsServiceClient, transports.PromotionsServiceRestTransport, "rest", "true"), + (PromotionsServiceClient, transports.PromotionsServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(PromotionsServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceClient)) +@mock.patch.object(PromotionsServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_promotions_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) + 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) + 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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", [ + PromotionsServiceClient, PromotionsServiceAsyncClient +]) +@mock.patch.object(PromotionsServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PromotionsServiceClient)) +@mock.patch.object(PromotionsServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PromotionsServiceAsyncClient)) +def test_promotions_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 + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + +@pytest.mark.parametrize("client_class", [ + PromotionsServiceClient, PromotionsServiceAsyncClient +]) +@mock.patch.object(PromotionsServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceClient)) +@mock.patch.object(PromotionsServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceAsyncClient)) +def test_promotions_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = PromotionsServiceClient._DEFAULT_UNIVERSE + default_endpoint = PromotionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) + mock_universe = "bar.com" + mock_endpoint = PromotionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel"): + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=api_override) + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + else: + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == (mock_endpoint if universe_exists else default_endpoint) + assert client.universe_domain == (mock_universe if universe_exists else default_universe) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc"), + (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (PromotionsServiceClient, transports.PromotionsServiceRestTransport, "rest"), +]) +def test_promotions_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + 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", [ + (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc", grpc_helpers), + (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (PromotionsServiceClient, transports.PromotionsServiceRestTransport, "rest", None), +]) +def test_promotions_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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_promotions_service_client_client_options_from_dict(): + with mock.patch('google.shopping.merchant_promotions_v1beta.services.promotions_service.transports.PromotionsServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = PromotionsServiceClient( + 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", [ + (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc", grpc_helpers), + (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_promotions_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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( + "merchantapi.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/content', +), + scopes=None, + default_host="merchantapi.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + promotions.InsertPromotionRequest, + dict, +]) +def test_insert_promotion(request_type, transport: str = 'grpc'): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.insert_promotion), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = promotions.Promotion( + name='name_value', + promotion_id='promotion_id_value', + content_language='content_language_value', + target_country='target_country_value', + redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], + data_source='data_source_value', + version_number=1518, + ) + response = client.insert_promotion(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = promotions.InsertPromotionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, promotions.Promotion) + assert response.name == 'name_value' + assert response.promotion_id == 'promotion_id_value' + assert response.content_language == 'content_language_value' + assert response.target_country == 'target_country_value' + assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] + assert response.data_source == 'data_source_value' + assert response.version_number == 1518 + + +def test_insert_promotion_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = promotions.InsertPromotionRequest( + parent='parent_value', + data_source='data_source_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.insert_promotion), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.insert_promotion(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == promotions.InsertPromotionRequest( + parent='parent_value', + data_source='data_source_value', + ) + +def test_insert_promotion_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.insert_promotion in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.insert_promotion] = mock_rpc + request = {} + client.insert_promotion(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.insert_promotion(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_insert_promotion_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.insert_promotion in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.insert_promotion] = mock_rpc + + request = {} + await client.insert_promotion(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.insert_promotion(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_insert_promotion_async(transport: str = 'grpc_asyncio', request_type=promotions.InsertPromotionRequest): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.insert_promotion), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion( + name='name_value', + promotion_id='promotion_id_value', + content_language='content_language_value', + target_country='target_country_value', + redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], + data_source='data_source_value', + version_number=1518, + )) + response = await client.insert_promotion(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = promotions.InsertPromotionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, promotions.Promotion) + assert response.name == 'name_value' + assert response.promotion_id == 'promotion_id_value' + assert response.content_language == 'content_language_value' + assert response.target_country == 'target_country_value' + assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] + assert response.data_source == 'data_source_value' + assert response.version_number == 1518 + + +@pytest.mark.asyncio +async def test_insert_promotion_async_from_dict(): + await test_insert_promotion_async(request_type=dict) + +def test_insert_promotion_field_headers(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = promotions.InsertPromotionRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.insert_promotion), + '__call__') as call: + call.return_value = promotions.Promotion() + client.insert_promotion(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_insert_promotion_field_headers_async(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = promotions.InsertPromotionRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.insert_promotion), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion()) + await client.insert_promotion(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", [ + promotions.GetPromotionRequest, + dict, +]) +def test_get_promotion(request_type, transport: str = 'grpc'): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_promotion), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = promotions.Promotion( + name='name_value', + promotion_id='promotion_id_value', + content_language='content_language_value', + target_country='target_country_value', + redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], + data_source='data_source_value', + version_number=1518, + ) + response = client.get_promotion(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = promotions.GetPromotionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, promotions.Promotion) + assert response.name == 'name_value' + assert response.promotion_id == 'promotion_id_value' + assert response.content_language == 'content_language_value' + assert response.target_country == 'target_country_value' + assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] + assert response.data_source == 'data_source_value' + assert response.version_number == 1518 + + +def test_get_promotion_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = promotions.GetPromotionRequest( + name='name_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_promotion), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.get_promotion(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == promotions.GetPromotionRequest( + name='name_value', + ) + +def test_get_promotion_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_promotion in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.get_promotion] = mock_rpc + request = {} + client.get_promotion(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_promotion(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_get_promotion_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.get_promotion in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.get_promotion] = mock_rpc + + request = {} + await client.get_promotion(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_promotion(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_get_promotion_async(transport: str = 'grpc_asyncio', request_type=promotions.GetPromotionRequest): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_promotion), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion( + name='name_value', + promotion_id='promotion_id_value', + content_language='content_language_value', + target_country='target_country_value', + redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], + data_source='data_source_value', + version_number=1518, + )) + response = await client.get_promotion(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = promotions.GetPromotionRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, promotions.Promotion) + assert response.name == 'name_value' + assert response.promotion_id == 'promotion_id_value' + assert response.content_language == 'content_language_value' + assert response.target_country == 'target_country_value' + assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] + assert response.data_source == 'data_source_value' + assert response.version_number == 1518 + + +@pytest.mark.asyncio +async def test_get_promotion_async_from_dict(): + await test_get_promotion_async(request_type=dict) + +def test_get_promotion_field_headers(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = promotions.GetPromotionRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_promotion), + '__call__') as call: + call.return_value = promotions.Promotion() + client.get_promotion(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_promotion_field_headers_async(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = promotions.GetPromotionRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_promotion), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion()) + await client.get_promotion(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_promotion_flattened(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_promotion), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = promotions.Promotion() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_promotion( + 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_promotion_flattened_error(): + client = PromotionsServiceClient( + 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_promotion( + promotions.GetPromotionRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_promotion_flattened_async(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_promotion), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = promotions.Promotion() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_promotion( + 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_promotion_flattened_error_async(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_promotion( + promotions.GetPromotionRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + promotions.ListPromotionsRequest, + dict, +]) +def test_list_promotions(request_type, transport: str = 'grpc'): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_promotions), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = promotions.ListPromotionsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_promotions(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = promotions.ListPromotionsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPromotionsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_promotions_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = promotions.ListPromotionsRequest( + parent='parent_value', + page_token='page_token_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_promotions), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.list_promotions(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == promotions.ListPromotionsRequest( + parent='parent_value', + page_token='page_token_value', + ) + +def test_list_promotions_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_promotions in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.list_promotions] = mock_rpc + request = {} + client.list_promotions(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_promotions(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_promotions_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.list_promotions in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.list_promotions] = mock_rpc + + request = {} + await client.list_promotions(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_promotions(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_promotions_async(transport: str = 'grpc_asyncio', request_type=promotions.ListPromotionsRequest): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_promotions), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(promotions.ListPromotionsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_promotions(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = promotions.ListPromotionsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPromotionsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_promotions_async_from_dict(): + await test_list_promotions_async(request_type=dict) + +def test_list_promotions_field_headers(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = promotions.ListPromotionsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_promotions), + '__call__') as call: + call.return_value = promotions.ListPromotionsResponse() + client.list_promotions(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_promotions_field_headers_async(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = promotions.ListPromotionsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_promotions), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.ListPromotionsResponse()) + await client.list_promotions(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_promotions_flattened(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_promotions), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = promotions.ListPromotionsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_promotions( + 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_promotions_flattened_error(): + client = PromotionsServiceClient( + 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_promotions( + promotions.ListPromotionsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_promotions_flattened_async(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_promotions), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = promotions.ListPromotionsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.ListPromotionsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_promotions( + 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_promotions_flattened_error_async(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_promotions( + promotions.ListPromotionsRequest(), + parent='parent_value', + ) + + +def test_list_promotions_pager(transport_name: str = "grpc"): + client = PromotionsServiceClient( + 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_promotions), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + promotions.Promotion(), + promotions.Promotion(), + ], + next_page_token='abc', + ), + promotions.ListPromotionsResponse( + promotions=[], + next_page_token='def', + ), + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + ], + next_page_token='ghi', + ), + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + promotions.Promotion(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_promotions(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, promotions.Promotion) + for i in results) +def test_list_promotions_pages(transport_name: str = "grpc"): + client = PromotionsServiceClient( + 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_promotions), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + promotions.Promotion(), + promotions.Promotion(), + ], + next_page_token='abc', + ), + promotions.ListPromotionsResponse( + promotions=[], + next_page_token='def', + ), + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + ], + next_page_token='ghi', + ), + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + promotions.Promotion(), + ], + ), + RuntimeError, + ) + pages = list(client.list_promotions(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_promotions_async_pager(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_promotions), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + promotions.Promotion(), + promotions.Promotion(), + ], + next_page_token='abc', + ), + promotions.ListPromotionsResponse( + promotions=[], + next_page_token='def', + ), + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + ], + next_page_token='ghi', + ), + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + promotions.Promotion(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_promotions(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, promotions.Promotion) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_promotions_async_pages(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_promotions), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + promotions.Promotion(), + promotions.Promotion(), + ], + next_page_token='abc', + ), + promotions.ListPromotionsResponse( + promotions=[], + next_page_token='def', + ), + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + ], + next_page_token='ghi', + ), + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + promotions.Promotion(), + ], + ), + 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_promotions(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_insert_promotion_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.insert_promotion in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.insert_promotion] = mock_rpc + + request = {} + client.insert_promotion(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.insert_promotion(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_insert_promotion_rest_required_fields(request_type=promotions.InsertPromotionRequest): + transport_class = transports.PromotionsServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["data_source"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).insert_promotion._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["dataSource"] = 'data_source_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).insert_promotion._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 "dataSource" in jsonified_request + assert jsonified_request["dataSource"] == 'data_source_value' + + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = promotions.Promotion() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = promotions.Promotion.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.insert_promotion(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_insert_promotion_rest_unset_required_fields(): + transport = transports.PromotionsServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.insert_promotion._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "promotion", "dataSource", ))) + + +def test_get_promotion_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_promotion in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.get_promotion] = mock_rpc + + request = {} + client.get_promotion(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_promotion(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_promotion_rest_required_fields(request_type=promotions.GetPromotionRequest): + transport_class = transports.PromotionsServiceRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_promotion._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_promotion._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 = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = promotions.Promotion() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = promotions.Promotion.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_promotion(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_promotion_rest_unset_required_fields(): + transport = transports.PromotionsServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_promotion._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +def test_get_promotion_rest_flattened(): + client = PromotionsServiceClient( + 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 = promotions.Promotion() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'accounts/sample1/promotions/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = promotions.Promotion.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_promotion(**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/promotions/v1beta/{name=accounts/*/promotions/*}" % client.transport._host, args[1]) + + +def test_get_promotion_rest_flattened_error(transport: str = 'rest'): + client = PromotionsServiceClient( + 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_promotion( + promotions.GetPromotionRequest(), + name='name_value', + ) + + +def test_list_promotions_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_promotions in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.list_promotions] = mock_rpc + + request = {} + client.list_promotions(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_promotions(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_promotions_rest_required_fields(request_type=promotions.ListPromotionsRequest): + transport_class = transports.PromotionsServiceRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_promotions._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_promotions._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 = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = promotions.ListPromotionsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = promotions.ListPromotionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_promotions(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_promotions_rest_unset_required_fields(): + transport = transports.PromotionsServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_promotions._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +def test_list_promotions_rest_flattened(): + client = PromotionsServiceClient( + 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 = promotions.ListPromotionsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'accounts/sample1'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = promotions.ListPromotionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_promotions(**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/promotions/v1beta/{parent=accounts/*}/promotions" % client.transport._host, args[1]) + + +def test_list_promotions_rest_flattened_error(transport: str = 'rest'): + client = PromotionsServiceClient( + 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_promotions( + promotions.ListPromotionsRequest(), + parent='parent_value', + ) + + +def test_list_promotions_rest_pager(transport: str = 'rest'): + client = PromotionsServiceClient( + 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 = ( + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + promotions.Promotion(), + promotions.Promotion(), + ], + next_page_token='abc', + ), + promotions.ListPromotionsResponse( + promotions=[], + next_page_token='def', + ), + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + ], + next_page_token='ghi', + ), + promotions.ListPromotionsResponse( + promotions=[ + promotions.Promotion(), + promotions.Promotion(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(promotions.ListPromotionsResponse.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': 'accounts/sample1'} + + pager = client.list_promotions(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, promotions.Promotion) + for i in results) + + pages = list(client.list_promotions(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.PromotionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.PromotionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PromotionsServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.PromotionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PromotionsServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PromotionsServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.PromotionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PromotionsServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.PromotionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = PromotionsServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.PromotionsServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.PromotionsServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.PromotionsServiceGrpcTransport, + transports.PromotionsServiceGrpcAsyncIOTransport, + transports.PromotionsServiceRestTransport, +]) +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() + +def test_transport_kind_grpc(): + transport = PromotionsServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_promotion_empty_call_grpc(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_promotion), + '__call__') as call: + call.return_value = promotions.Promotion() + client.insert_promotion(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.InsertPromotionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_promotion_empty_call_grpc(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_promotion), + '__call__') as call: + call.return_value = promotions.Promotion() + client.get_promotion(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.GetPromotionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_promotions_empty_call_grpc(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_promotions), + '__call__') as call: + call.return_value = promotions.ListPromotionsResponse() + client.list_promotions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.ListPromotionsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = PromotionsServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_insert_promotion_empty_call_grpc_asyncio(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_promotion), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion( + name='name_value', + promotion_id='promotion_id_value', + content_language='content_language_value', + target_country='target_country_value', + redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], + data_source='data_source_value', + version_number=1518, + )) + await client.insert_promotion(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.InsertPromotionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_promotion_empty_call_grpc_asyncio(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_promotion), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion( + name='name_value', + promotion_id='promotion_id_value', + content_language='content_language_value', + target_country='target_country_value', + redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], + data_source='data_source_value', + version_number=1518, + )) + await client.get_promotion(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.GetPromotionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_promotions_empty_call_grpc_asyncio(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_promotions), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.ListPromotionsResponse( + next_page_token='next_page_token_value', + )) + await client.list_promotions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.ListPromotionsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = PromotionsServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_insert_promotion_rest_bad_request(request_type=promotions.InsertPromotionRequest): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'parent': 'accounts/sample1'} + 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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.insert_promotion(request) + + +@pytest.mark.parametrize("request_type", [ + promotions.InsertPromotionRequest, + dict, +]) +def test_insert_promotion_rest_call_success(request_type): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'accounts/sample1'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = promotions.Promotion( + name='name_value', + promotion_id='promotion_id_value', + content_language='content_language_value', + target_country='target_country_value', + redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], + data_source='data_source_value', + version_number=1518, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = promotions.Promotion.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.insert_promotion(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, promotions.Promotion) + assert response.name == 'name_value' + assert response.promotion_id == 'promotion_id_value' + assert response.content_language == 'content_language_value' + assert response.target_country == 'target_country_value' + assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] + assert response.data_source == 'data_source_value' + assert response.version_number == 1518 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_insert_promotion_rest_interceptors(null_interceptor): + transport = transports.PromotionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.PromotionsServiceRestInterceptor(), + ) + client = PromotionsServiceClient(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.PromotionsServiceRestInterceptor, "post_insert_promotion") as post, \ + mock.patch.object(transports.PromotionsServiceRestInterceptor, "pre_insert_promotion") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = promotions.InsertPromotionRequest.pb(promotions.InsertPromotionRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = promotions.Promotion.to_json(promotions.Promotion()) + req.return_value.content = return_value + + request = promotions.InsertPromotionRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = promotions.Promotion() + + client.insert_promotion(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_promotion_rest_bad_request(request_type=promotions.GetPromotionRequest): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'name': 'accounts/sample1/promotions/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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_promotion(request) + + +@pytest.mark.parametrize("request_type", [ + promotions.GetPromotionRequest, + dict, +]) +def test_get_promotion_rest_call_success(request_type): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'accounts/sample1/promotions/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 = promotions.Promotion( + name='name_value', + promotion_id='promotion_id_value', + content_language='content_language_value', + target_country='target_country_value', + redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], + data_source='data_source_value', + version_number=1518, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = promotions.Promotion.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_promotion(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, promotions.Promotion) + assert response.name == 'name_value' + assert response.promotion_id == 'promotion_id_value' + assert response.content_language == 'content_language_value' + assert response.target_country == 'target_country_value' + assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] + assert response.data_source == 'data_source_value' + assert response.version_number == 1518 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_promotion_rest_interceptors(null_interceptor): + transport = transports.PromotionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.PromotionsServiceRestInterceptor(), + ) + client = PromotionsServiceClient(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.PromotionsServiceRestInterceptor, "post_get_promotion") as post, \ + mock.patch.object(transports.PromotionsServiceRestInterceptor, "pre_get_promotion") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = promotions.GetPromotionRequest.pb(promotions.GetPromotionRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = promotions.Promotion.to_json(promotions.Promotion()) + req.return_value.content = return_value + + request = promotions.GetPromotionRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = promotions.Promotion() + + client.get_promotion(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_promotions_rest_bad_request(request_type=promotions.ListPromotionsRequest): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'parent': 'accounts/sample1'} + 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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_promotions(request) + + +@pytest.mark.parametrize("request_type", [ + promotions.ListPromotionsRequest, + dict, +]) +def test_list_promotions_rest_call_success(request_type): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'accounts/sample1'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = promotions.ListPromotionsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = promotions.ListPromotionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_promotions(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPromotionsPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_promotions_rest_interceptors(null_interceptor): + transport = transports.PromotionsServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.PromotionsServiceRestInterceptor(), + ) + client = PromotionsServiceClient(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.PromotionsServiceRestInterceptor, "post_list_promotions") as post, \ + mock.patch.object(transports.PromotionsServiceRestInterceptor, "pre_list_promotions") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = promotions.ListPromotionsRequest.pb(promotions.ListPromotionsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = promotions.ListPromotionsResponse.to_json(promotions.ListPromotionsResponse()) + req.return_value.content = return_value + + request = promotions.ListPromotionsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = promotions.ListPromotionsResponse() + + client.list_promotions(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + +def test_initialize_client_w_rest(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_insert_promotion_empty_call_rest(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.insert_promotion), + '__call__') as call: + client.insert_promotion(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.InsertPromotionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_promotion_empty_call_rest(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_promotion), + '__call__') as call: + client.get_promotion(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.GetPromotionRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_promotions_empty_call_rest(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_promotions), + '__call__') as call: + client.list_promotions(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = promotions.ListPromotionsRequest() + + assert args[0] == request_msg + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.PromotionsServiceGrpcTransport, + ) + +def test_promotions_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.PromotionsServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_promotions_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.shopping.merchant_promotions_v1beta.services.promotions_service.transports.PromotionsServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.PromotionsServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'insert_promotion', + 'get_promotion', + 'list_promotions', + ) + 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_promotions_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.shopping.merchant_promotions_v1beta.services.promotions_service.transports.PromotionsServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.PromotionsServiceTransport( + 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/content', +), + quota_project_id="octopus", + ) + + +def test_promotions_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.shopping.merchant_promotions_v1beta.services.promotions_service.transports.PromotionsServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.PromotionsServiceTransport() + adc.assert_called_once() + + +def test_promotions_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) + PromotionsServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/content', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PromotionsServiceGrpcTransport, + transports.PromotionsServiceGrpcAsyncIOTransport, + ], +) +def test_promotions_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/content',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PromotionsServiceGrpcTransport, + transports.PromotionsServiceGrpcAsyncIOTransport, + transports.PromotionsServiceRestTransport, + ], +) +def test_promotions_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.PromotionsServiceGrpcTransport, grpc_helpers), + (transports.PromotionsServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_promotions_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( + "merchantapi.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/content', +), + scopes=["1", "2"], + default_host="merchantapi.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.PromotionsServiceGrpcTransport, transports.PromotionsServiceGrpcAsyncIOTransport]) +def test_promotions_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_promotions_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.PromotionsServiceRestTransport ( + 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_promotions_service_host_no_port(transport_name): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='merchantapi.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'merchantapi.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://merchantapi.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_promotions_service_host_with_port(transport_name): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='merchantapi.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'merchantapi.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://merchantapi.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_promotions_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = PromotionsServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = PromotionsServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.insert_promotion._session + session2 = client2.transport.insert_promotion._session + assert session1 != session2 + session1 = client1.transport.get_promotion._session + session2 = client2.transport.get_promotion._session + assert session1 != session2 + session1 = client1.transport.list_promotions._session + session2 = client2.transport.list_promotions._session + assert session1 != session2 +def test_promotions_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.PromotionsServiceGrpcTransport( + 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_promotions_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.PromotionsServiceGrpcAsyncIOTransport( + 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.PromotionsServiceGrpcTransport, transports.PromotionsServiceGrpcAsyncIOTransport]) +def test_promotions_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.PromotionsServiceGrpcTransport, transports.PromotionsServiceGrpcAsyncIOTransport]) +def test_promotions_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_promotion_path(): + account = "squid" + promotion = "clam" + expected = "accounts/{account}/promotions/{promotion}".format(account=account, promotion=promotion, ) + actual = PromotionsServiceClient.promotion_path(account, promotion) + assert expected == actual + + +def test_parse_promotion_path(): + expected = { + "account": "whelk", + "promotion": "octopus", + } + path = PromotionsServiceClient.promotion_path(**expected) + + # Check that the path construction is reversible. + actual = PromotionsServiceClient.parse_promotion_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "oyster" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = PromotionsServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nudibranch", + } + path = PromotionsServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = PromotionsServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "cuttlefish" + expected = "folders/{folder}".format(folder=folder, ) + actual = PromotionsServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "mussel", + } + path = PromotionsServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = PromotionsServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "winkle" + expected = "organizations/{organization}".format(organization=organization, ) + actual = PromotionsServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nautilus", + } + path = PromotionsServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = PromotionsServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "scallop" + expected = "projects/{project}".format(project=project, ) + actual = PromotionsServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "abalone", + } + path = PromotionsServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = PromotionsServiceClient.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 = PromotionsServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "whelk", + "location": "octopus", + } + path = PromotionsServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = PromotionsServiceClient.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.PromotionsServiceTransport, '_prep_wrapped_messages') as prep: + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.PromotionsServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = PromotionsServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_grpc(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc" + ) + with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = PromotionsServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio" + ) + with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close_rest(): + client = PromotionsServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + with mock.patch.object(type(getattr(client.transport, "_session")), "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 = PromotionsServiceClient( + 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", [ + (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport), + (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport), +]) +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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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/google-shopping-merchant-quota/v1beta/.coveragerc b/owl-bot-staging/google-shopping-merchant-quota/v1beta/.coveragerc new file mode 100644 index 000000000000..8114816bc3c5 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/shopping/merchant_quota/__init__.py + google/shopping/merchant_quota/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/google-shopping-merchant-quota/v1beta/.flake8 b/owl-bot-staging/google-shopping-merchant-quota/v1beta/.flake8 new file mode 100644 index 000000000000..29227d4cf419 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/.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/google-shopping-merchant-quota/v1beta/MANIFEST.in b/owl-bot-staging/google-shopping-merchant-quota/v1beta/MANIFEST.in new file mode 100644 index 000000000000..e1f38916c325 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include google/shopping/merchant_quota *.py +recursive-include google/shopping/merchant_quota_v1beta *.py diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/README.rst b/owl-bot-staging/google-shopping-merchant-quota/v1beta/README.rst new file mode 100644 index 000000000000..ffa65e82132a --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/README.rst @@ -0,0 +1,49 @@ +Python Client for Google Shopping Merchant Quota 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 Shopping Merchant Quota 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/google-shopping-merchant-quota/v1beta/docs/_static/custom.css b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/_static/custom.css new file mode 100644 index 000000000000..06423be0b592 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/_static/custom.css @@ -0,0 +1,3 @@ +dl.field-list > dt { + min-width: 100px +} diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/conf.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/conf.py new file mode 100644 index 000000000000..a76827c00d4d --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/conf.py @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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-shopping-merchant-quota 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-shopping-merchant-quota" +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 Shopping 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-shopping-merchant-quota-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-shopping-merchant-quota.tex", + u"google-shopping-merchant-quota 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-shopping-merchant-quota", + u"Google Shopping Merchant Quota 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-shopping-merchant-quota", + u"google-shopping-merchant-quota Documentation", + author, + "google-shopping-merchant-quota", + "GAPIC library for Google Shopping Merchant Quota 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/google-shopping-merchant-quota/v1beta/docs/index.rst b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/index.rst new file mode 100644 index 000000000000..c688ba3396e1 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + merchant_quota_v1beta/services_ + merchant_quota_v1beta/types_ diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/quota_service.rst b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/quota_service.rst new file mode 100644 index 000000000000..1743e25da211 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/quota_service.rst @@ -0,0 +1,10 @@ +QuotaService +------------------------------ + +.. automodule:: google.shopping.merchant_quota_v1beta.services.quota_service + :members: + :inherited-members: + +.. automodule:: google.shopping.merchant_quota_v1beta.services.quota_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/services_.rst b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/services_.rst new file mode 100644 index 000000000000..0928f3a6f1ce --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/services_.rst @@ -0,0 +1,6 @@ +Services for Google Shopping Merchant Quota v1beta API +====================================================== +.. toctree:: + :maxdepth: 2 + + quota_service diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/types_.rst b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/types_.rst new file mode 100644 index 000000000000..622859fdaffb --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/types_.rst @@ -0,0 +1,6 @@ +Types for Google Shopping Merchant Quota v1beta API +=================================================== + +.. automodule:: google.shopping.merchant_quota_v1beta.types + :members: + :show-inheritance: diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/__init__.py new file mode 100644 index 000000000000..c3a300a10746 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.shopping.merchant_quota import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.shopping.merchant_quota_v1beta.services.quota_service.client import QuotaServiceClient +from google.shopping.merchant_quota_v1beta.services.quota_service.async_client import QuotaServiceAsyncClient + +from google.shopping.merchant_quota_v1beta.types.quota import ListQuotaGroupsRequest +from google.shopping.merchant_quota_v1beta.types.quota import ListQuotaGroupsResponse +from google.shopping.merchant_quota_v1beta.types.quota import MethodDetails +from google.shopping.merchant_quota_v1beta.types.quota import QuotaGroup + +__all__ = ('QuotaServiceClient', + 'QuotaServiceAsyncClient', + 'ListQuotaGroupsRequest', + 'ListQuotaGroupsResponse', + 'MethodDetails', + 'QuotaGroup', +) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/gapic_version.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/gapic_version.py new file mode 100644 index 000000000000..558c8aab67c5 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/py.typed b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/py.typed new file mode 100644 index 000000000000..c73143bc3edf --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-shopping-merchant-quota package uses inline types. diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/__init__.py new file mode 100644 index 000000000000..d5c60977b344 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.shopping.merchant_quota_v1beta import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.quota_service import QuotaServiceClient +from .services.quota_service import QuotaServiceAsyncClient + +from .types.quota import ListQuotaGroupsRequest +from .types.quota import ListQuotaGroupsResponse +from .types.quota import MethodDetails +from .types.quota import QuotaGroup + +__all__ = ( + 'QuotaServiceAsyncClient', +'ListQuotaGroupsRequest', +'ListQuotaGroupsResponse', +'MethodDetails', +'QuotaGroup', +'QuotaServiceClient', +) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_metadata.json b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_metadata.json new file mode 100644 index 000000000000..8278f93d2b60 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_metadata.json @@ -0,0 +1,43 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.shopping.merchant_quota_v1beta", + "protoPackage": "google.shopping.merchant.quota.v1beta", + "schema": "1.0", + "services": { + "QuotaService": { + "clients": { + "grpc": { + "libraryClient": "QuotaServiceClient", + "rpcs": { + "ListQuotaGroups": { + "methods": [ + "list_quota_groups" + ] + } + } + }, + "grpc-async": { + "libraryClient": "QuotaServiceAsyncClient", + "rpcs": { + "ListQuotaGroups": { + "methods": [ + "list_quota_groups" + ] + } + } + }, + "rest": { + "libraryClient": "QuotaServiceClient", + "rpcs": { + "ListQuotaGroups": { + "methods": [ + "list_quota_groups" + ] + } + } + } + } + } + } +} diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_version.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_version.py new file mode 100644 index 000000000000..558c8aab67c5 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/py.typed b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/py.typed new file mode 100644 index 000000000000..c73143bc3edf --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-shopping-merchant-quota package uses inline types. diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/__init__.py new file mode 100644 index 000000000000..8f6cf068242c --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/__init__.py new file mode 100644 index 000000000000..512b8ee436f7 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 QuotaServiceClient +from .async_client import QuotaServiceAsyncClient + +__all__ = ( + 'QuotaServiceClient', + 'QuotaServiceAsyncClient', +) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/async_client.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/async_client.py new file mode 100644 index 000000000000..7c54e59b44d4 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/async_client.py @@ -0,0 +1,360 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 re +from typing import Dict, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.shopping.merchant_quota_v1beta 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_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.shopping.merchant_quota_v1beta.services.quota_service import pagers +from google.shopping.merchant_quota_v1beta.types import quota +from .transports.base import QuotaServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import QuotaServiceGrpcAsyncIOTransport +from .client import QuotaServiceClient + + +class QuotaServiceAsyncClient: + """Service to get method call quota information per Merchant API + method. + """ + + _client: QuotaServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = QuotaServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = QuotaServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = QuotaServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = QuotaServiceClient._DEFAULT_UNIVERSE + + quota_group_path = staticmethod(QuotaServiceClient.quota_group_path) + parse_quota_group_path = staticmethod(QuotaServiceClient.parse_quota_group_path) + common_billing_account_path = staticmethod(QuotaServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(QuotaServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(QuotaServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(QuotaServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(QuotaServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(QuotaServiceClient.parse_common_organization_path) + common_project_path = staticmethod(QuotaServiceClient.common_project_path) + parse_common_project_path = staticmethod(QuotaServiceClient.parse_common_project_path) + common_location_path = staticmethod(QuotaServiceClient.common_location_path) + parse_common_location_path = staticmethod(QuotaServiceClient.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: + QuotaServiceAsyncClient: The constructed client. + """ + return QuotaServiceClient.from_service_account_info.__func__(QuotaServiceAsyncClient, 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: + QuotaServiceAsyncClient: The constructed client. + """ + return QuotaServiceClient.from_service_account_file.__func__(QuotaServiceAsyncClient, 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 QuotaServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> QuotaServiceTransport: + """Returns the transport used by the client instance. + + Returns: + QuotaServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = QuotaServiceClient.get_transport_class + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, QuotaServiceTransport, Callable[..., QuotaServiceTransport]]] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the quota service async 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 (Optional[Union[str,QuotaServiceTransport,Callable[..., QuotaServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the QuotaServiceTransport constructor. + 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. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client = QuotaServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def list_quota_groups(self, + request: Optional[Union[quota.ListQuotaGroupsRequest, 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.ListQuotaGroupsAsyncPager: + r"""Lists the daily call quota and usage per group for + your Merchant Center account. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.shopping import merchant_quota_v1beta + + async def sample_list_quota_groups(): + # Create a client + client = merchant_quota_v1beta.QuotaServiceAsyncClient() + + # Initialize request argument(s) + request = merchant_quota_v1beta.ListQuotaGroupsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_quota_groups(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsRequest, dict]]): + The request object. Request message for the + ListQuotaGroups method. + parent (:class:`str`): + Required. The merchant account who + owns the collection of method quotas + Format: accounts/{account} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.shopping.merchant_quota_v1beta.services.quota_service.pagers.ListQuotaGroupsAsyncPager: + Response message for the + ListMethodGroups 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.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, quota.ListQuotaGroupsRequest): + request = quota.ListQuotaGroupsRequest(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._client._transport._wrapped_methods[self._client._transport.list_quota_groups] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListQuotaGroupsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "QuotaServiceAsyncClient": + 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__ = ( + "QuotaServiceAsyncClient", +) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/client.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/client.py new file mode 100644 index 000000000000..0d09cf485cfe --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/client.py @@ -0,0 +1,716 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.shopping.merchant_quota_v1beta 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, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +from google.shopping.merchant_quota_v1beta.services.quota_service import pagers +from google.shopping.merchant_quota_v1beta.types import quota +from .transports.base import QuotaServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import QuotaServiceGrpcTransport +from .transports.grpc_asyncio import QuotaServiceGrpcAsyncIOTransport +from .transports.rest import QuotaServiceRestTransport + + +class QuotaServiceClientMeta(type): + """Metaclass for the QuotaService 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[QuotaServiceTransport]] + _transport_registry["grpc"] = QuotaServiceGrpcTransport + _transport_registry["grpc_asyncio"] = QuotaServiceGrpcAsyncIOTransport + _transport_registry["rest"] = QuotaServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[QuotaServiceTransport]: + """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 QuotaServiceClient(metaclass=QuotaServiceClientMeta): + """Service to get method call quota information per Merchant API + method. + """ + + @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") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "merchantapi.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "merchantapi.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @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: + QuotaServiceClient: 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: + QuotaServiceClient: 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) -> QuotaServiceTransport: + """Returns the transport used by the client instance. + + Returns: + QuotaServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def quota_group_path(account: str,group: str,) -> str: + """Returns a fully-qualified quota_group string.""" + return "accounts/{account}/groups/{group}".format(account=account, group=group, ) + + @staticmethod + def parse_quota_group_path(path: str) -> Dict[str,str]: + """Parses a quota_group path into its component segments.""" + m = re.match(r"^accounts/(?P.+?)/groups/(?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): + """Deprecated. 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. + """ + + warnings.warn("get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning) + 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 + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false").lower() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + 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`") + return use_client_cert == "true", use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint(api_override, client_cert_source, universe_domain, use_mtls_endpoint): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + _default_universe = QuotaServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError(f"mTLS is not supported in any universe other than {_default_universe}.") + api_endpoint = QuotaServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = QuotaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=universe_domain) + return api_endpoint + + @staticmethod + def _get_universe_domain(client_universe_domain: Optional[str], universe_domain_env: Optional[str]) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = QuotaServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + @staticmethod + def _compare_universes(client_universe: str, + credentials: ga_credentials.Credentials) -> bool: + """Returns True iff the universe domains used by the client and credentials match. + + Args: + client_universe (str): The universe domain configured via the client options. + credentials (ga_credentials.Credentials): The credentials being used in the client. + + Returns: + bool: True iff client_universe matches the universe in credentials. + + Raises: + ValueError: when client_universe does not match the universe in credentials. + """ + + default_universe = QuotaServiceClient._DEFAULT_UNIVERSE + credentials_universe = getattr(credentials, "universe_domain", default_universe) + + if client_universe != credentials_universe: + raise ValueError("The configured universe domain " + f"({client_universe}) does not match the universe domain " + f"found in the credentials ({credentials_universe}). " + "If you haven't configured the universe domain explicitly, " + f"`{default_universe}` is the default.") + return True + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + self._is_universe_domain_valid = (self._is_universe_domain_valid or + QuotaServiceClient._compare_universes(self.universe_domain, self.transport._credentials)) + return self._is_universe_domain_valid + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, QuotaServiceTransport, Callable[..., QuotaServiceTransport]]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the quota 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 (Optional[Union[str,QuotaServiceTransport,Callable[..., QuotaServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the QuotaServiceTransport constructor. + 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. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast(client_options_lib.ClientOptions, self._client_options) + + universe_domain_opt = getattr(self._client_options, 'universe_domain', None) + + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = QuotaServiceClient._read_environment_variables() + self._client_cert_source = QuotaServiceClient._get_client_cert_source(self._client_options.client_cert_source, self._use_client_cert) + self._universe_domain = QuotaServiceClient._get_universe_domain(universe_domain_opt, self._universe_domain_env) + self._api_endpoint = None # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + api_key_value = getattr(self._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. + transport_provided = isinstance(transport, QuotaServiceTransport) + if transport_provided: + # transport is a QuotaServiceTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(QuotaServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = (self._api_endpoint or + QuotaServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint)) + + if not transport_provided: + 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_init: Union[Type[QuotaServiceTransport], Callable[..., QuotaServiceTransport]] = ( + QuotaServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., QuotaServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + def list_quota_groups(self, + request: Optional[Union[quota.ListQuotaGroupsRequest, 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.ListQuotaGroupsPager: + r"""Lists the daily call quota and usage per group for + your Merchant Center account. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.shopping import merchant_quota_v1beta + + def sample_list_quota_groups(): + # Create a client + client = merchant_quota_v1beta.QuotaServiceClient() + + # Initialize request argument(s) + request = merchant_quota_v1beta.ListQuotaGroupsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_quota_groups(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsRequest, dict]): + The request object. Request message for the + ListQuotaGroups method. + parent (str): + Required. The merchant account who + owns the collection of method quotas + Format: accounts/{account} + + 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.shopping.merchant_quota_v1beta.services.quota_service.pagers.ListQuotaGroupsPager: + Response message for the + ListMethodGroups 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.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, quota.ListQuotaGroupsRequest): + request = quota.ListQuotaGroupsRequest(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_quota_groups] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListQuotaGroupsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "QuotaServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "QuotaServiceClient", +) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/pagers.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/pagers.py new file mode 100644 index 000000000000..6b1ff68f444d --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/pagers.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async +from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator, Union +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.shopping.merchant_quota_v1beta.types import quota + + +class ListQuotaGroupsPager: + """A pager for iterating through ``list_quota_groups`` requests. + + This class thinly wraps an initial + :class:`google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``quota_groups`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListQuotaGroups`` requests and continue to iterate + through the ``quota_groups`` field on the + corresponding responses. + + All the usual :class:`google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsResponse` + 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[..., quota.ListQuotaGroupsResponse], + request: quota.ListQuotaGroupsRequest, + response: quota.ListQuotaGroupsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsRequest): + The initial request object. + response (google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsResponse): + The initial response object. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = quota.ListQuotaGroupsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[quota.ListQuotaGroupsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, retry=self._retry, timeout=self._timeout, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[quota.QuotaGroup]: + for page in self.pages: + yield from page.quota_groups + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListQuotaGroupsAsyncPager: + """A pager for iterating through ``list_quota_groups`` requests. + + This class thinly wraps an initial + :class:`google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``quota_groups`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListQuotaGroups`` requests and continue to iterate + through the ``quota_groups`` field on the + corresponding responses. + + All the usual :class:`google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsResponse` + 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[quota.ListQuotaGroupsResponse]], + request: quota.ListQuotaGroupsRequest, + response: quota.ListQuotaGroupsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsRequest): + The initial request object. + response (google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = quota.ListQuotaGroupsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[quota.ListQuotaGroupsResponse]: + 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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[quota.QuotaGroup]: + async def async_generator(): + async for page in self.pages: + for response in page.quota_groups: + 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/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/README.rst b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/README.rst new file mode 100644 index 000000000000..06b6eb4da828 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`QuotaServiceTransport` is the ABC for all transports. +- public child `QuotaServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `QuotaServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseQuotaServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `QuotaServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/__init__.py new file mode 100644 index 000000000000..1dddb73e2611 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 QuotaServiceTransport +from .grpc import QuotaServiceGrpcTransport +from .grpc_asyncio import QuotaServiceGrpcAsyncIOTransport +from .rest import QuotaServiceRestTransport +from .rest import QuotaServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[QuotaServiceTransport]] +_transport_registry['grpc'] = QuotaServiceGrpcTransport +_transport_registry['grpc_asyncio'] = QuotaServiceGrpcAsyncIOTransport +_transport_registry['rest'] = QuotaServiceRestTransport + +__all__ = ( + 'QuotaServiceTransport', + 'QuotaServiceGrpcTransport', + 'QuotaServiceGrpcAsyncIOTransport', + 'QuotaServiceRestTransport', + 'QuotaServiceRestInterceptor', +) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/base.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/base.py new file mode 100644 index 000000000000..b4e3103cc44f --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.shopping.merchant_quota_v1beta 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.shopping.merchant_quota_v1beta.types import quota + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class QuotaServiceTransport(abc.ABC): + """Abstract transport class for QuotaService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/content', + ) + + DEFAULT_HOST: str = 'merchantapi.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 (default: 'merchantapi.googleapis.com'). + 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 not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # 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 and not self._ignore_credentials: + 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 + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.list_quota_groups: gapic_v1.method.wrap_method( + self.list_quota_groups, + 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_quota_groups(self) -> Callable[ + [quota.ListQuotaGroupsRequest], + Union[ + quota.ListQuotaGroupsResponse, + Awaitable[quota.ListQuotaGroupsResponse] + ]]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'QuotaServiceTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc.py new file mode 100644 index 000000000000..c052051bf10f --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc.py @@ -0,0 +1,272 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.shopping.merchant_quota_v1beta.types import quota +from .base import QuotaServiceTransport, DEFAULT_CLIENT_INFO + + +class QuotaServiceGrpcTransport(QuotaServiceTransport): + """gRPC backend transport for QuotaService. + + Service to get method call quota information per Merchant API + method. + + 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 = 'merchantapi.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[grpc.Channel, Callable[..., 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 (default: 'merchantapi.googleapis.com'). + 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 a ``channel`` instance 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 a ``channel`` instance is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # 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: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + 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 = 'merchantapi.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_quota_groups(self) -> Callable[ + [quota.ListQuotaGroupsRequest], + quota.ListQuotaGroupsResponse]: + r"""Return a callable for the list quota groups method over gRPC. + + Lists the daily call quota and usage per group for + your Merchant Center account. + + Returns: + Callable[[~.ListQuotaGroupsRequest], + ~.ListQuotaGroupsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_quota_groups' not in self._stubs: + self._stubs['list_quota_groups'] = self.grpc_channel.unary_unary( + '/google.shopping.merchant.quota.v1beta.QuotaService/ListQuotaGroups', + request_serializer=quota.ListQuotaGroupsRequest.serialize, + response_deserializer=quota.ListQuotaGroupsResponse.deserialize, + ) + return self._stubs['list_quota_groups'] + + def close(self): + self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'QuotaServiceGrpcTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py new file mode 100644 index 000000000000..9ca22a02ebce --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py @@ -0,0 +1,293 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 inspect +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 exceptions as core_exceptions +from google.api_core import retry_async as retries +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.shopping.merchant_quota_v1beta.types import quota +from .base import QuotaServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import QuotaServiceGrpcTransport + + +class QuotaServiceGrpcAsyncIOTransport(QuotaServiceTransport): + """gRPC AsyncIO backend transport for QuotaService. + + Service to get method call quota information per Merchant API + method. + + 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 = 'merchantapi.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`. + 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 = 'merchantapi.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[aio.Channel, Callable[..., 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 (default: 'merchantapi.googleapis.com'). + 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 a ``channel`` instance 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 a ``channel`` instance 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[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # 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: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + 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._wrap_with_kind = "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + 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_quota_groups(self) -> Callable[ + [quota.ListQuotaGroupsRequest], + Awaitable[quota.ListQuotaGroupsResponse]]: + r"""Return a callable for the list quota groups method over gRPC. + + Lists the daily call quota and usage per group for + your Merchant Center account. + + Returns: + Callable[[~.ListQuotaGroupsRequest], + Awaitable[~.ListQuotaGroupsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_quota_groups' not in self._stubs: + self._stubs['list_quota_groups'] = self.grpc_channel.unary_unary( + '/google.shopping.merchant.quota.v1beta.QuotaService/ListQuotaGroups', + request_serializer=quota.ListQuotaGroupsRequest.serialize, + response_deserializer=quota.ListQuotaGroupsResponse.deserialize, + ) + return self._stubs['list_quota_groups'] + + def _prep_wrapped_messages(self, client_info): + """ Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.list_quota_groups: self._wrap_method( + self.list_quota_groups, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ( + 'QuotaServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py new file mode 100644 index 000000000000..bd44e7b6b0a0 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py @@ -0,0 +1,276 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 +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 gapic_v1 + +from google.protobuf import json_format + +from requests import __version__ as requests_version +import dataclasses +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + + +from google.shopping.merchant_quota_v1beta.types import quota + + +from .rest_base import _BaseQuotaServiceRestTransport +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + + +class QuotaServiceRestInterceptor: + """Interceptor for QuotaService. + + 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 QuotaServiceRestTransport. + + .. code-block:: python + class MyCustomQuotaServiceInterceptor(QuotaServiceRestInterceptor): + def pre_list_quota_groups(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_quota_groups(self, response): + logging.log(f"Received response: {response}") + return response + + transport = QuotaServiceRestTransport(interceptor=MyCustomQuotaServiceInterceptor()) + client = QuotaServiceClient(transport=transport) + + + """ + def pre_list_quota_groups(self, request: quota.ListQuotaGroupsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[quota.ListQuotaGroupsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_quota_groups + + Override in a subclass to manipulate the request or metadata + before they are sent to the QuotaService server. + """ + return request, metadata + + def post_list_quota_groups(self, response: quota.ListQuotaGroupsResponse) -> quota.ListQuotaGroupsResponse: + """Post-rpc interceptor for list_quota_groups + + Override in a subclass to manipulate the response + after it is returned by the QuotaService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class QuotaServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: QuotaServiceRestInterceptor + + +class QuotaServiceRestTransport(_BaseQuotaServiceRestTransport): + """REST backend synchronous transport for QuotaService. + + Service to get method call quota information per Merchant API + method. + + 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 = 'merchantapi.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[QuotaServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + 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 + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + 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 QuotaServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _ListQuotaGroups(_BaseQuotaServiceRestTransport._BaseListQuotaGroups, QuotaServiceRestStub): + def __hash__(self): + return hash("QuotaServiceRestTransport.ListQuotaGroups") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__(self, + request: quota.ListQuotaGroupsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> quota.ListQuotaGroupsResponse: + r"""Call the list quota groups method over HTTP. + + Args: + request (~.quota.ListQuotaGroupsRequest): + The request object. Request message for the + ListQuotaGroups method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.quota.ListQuotaGroupsResponse: + Response message for the + ListMethodGroups method. + + """ + + http_options = _BaseQuotaServiceRestTransport._BaseListQuotaGroups._get_http_options() + request, metadata = self._interceptor.pre_list_quota_groups(request, metadata) + transcoded_request = _BaseQuotaServiceRestTransport._BaseListQuotaGroups._get_transcoded_request(http_options, request) + + # Jsonify the query params + query_params = _BaseQuotaServiceRestTransport._BaseListQuotaGroups._get_query_params_json(transcoded_request) + + # Send the request + response = QuotaServiceRestTransport._ListQuotaGroups._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) + + # 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 = quota.ListQuotaGroupsResponse() + pb_resp = quota.ListQuotaGroupsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_quota_groups(resp) + return resp + + @property + def list_quota_groups(self) -> Callable[ + [quota.ListQuotaGroupsRequest], + quota.ListQuotaGroupsResponse]: + # 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._ListQuotaGroups(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'QuotaServiceRestTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest_base.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest_base.py new file mode 100644 index 000000000000..c7b406f9d383 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest_base.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 json # type: ignore +from google.api_core import path_template +from google.api_core import gapic_v1 + +from google.protobuf import json_format +from .base import QuotaServiceTransport, DEFAULT_CLIENT_INFO + +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + + +from google.shopping.merchant_quota_v1beta.types import quota + + +class _BaseQuotaServiceRestTransport(QuotaServiceTransport): + """Base REST backend transport for QuotaService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + 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 = 'merchantapi.googleapis.com', + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = 'https', + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): 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. + 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 + 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 + ) + + class _BaseListQuotaGroups: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/quota/v1beta/{parent=accounts/*}/quotas', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = quota.ListQuotaGroupsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseQuotaServiceRestTransport._BaseListQuotaGroups._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__=( + '_BaseQuotaServiceRestTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/__init__.py new file mode 100644 index 000000000000..e4e09c52c9f5 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/__init__.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .quota import ( + ListQuotaGroupsRequest, + ListQuotaGroupsResponse, + MethodDetails, + QuotaGroup, +) + +__all__ = ( + 'ListQuotaGroupsRequest', + 'ListQuotaGroupsResponse', + 'MethodDetails', + 'QuotaGroup', +) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/quota.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/quota.py new file mode 100644 index 000000000000..c1a3a79456e3 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/quota.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.shopping.merchant.quota.v1beta', + manifest={ + 'QuotaGroup', + 'MethodDetails', + 'ListQuotaGroupsRequest', + 'ListQuotaGroupsResponse', + }, +) + + +class QuotaGroup(proto.Message): + r"""The group information for methods in the Merchant API. The + quota is shared between all methods in the group. Even if none + of the methods within the group have usage the information for + the group is returned. + + Attributes: + name (str): + Identifier. The resource name of the quota + group. Format: accounts/{account}/quotas/{group} + Note: There is no guarantee on the format of + {group} + quota_usage (int): + Output only. The current quota usage, meaning + the number of calls already made on a given day + to the methods in the group. The daily quota + limits reset at at 12:00 PM midday UTC. + quota_limit (int): + Output only. The maximum number of calls + allowed per day for the group. + quota_minute_limit (int): + Output only. The maximum number of calls + allowed per minute for the group. + method_details (MutableSequence[google.shopping.merchant_quota_v1beta.types.MethodDetails]): + Output only. List of all methods group quota + applies to. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + quota_usage: int = proto.Field( + proto.INT64, + number=2, + ) + quota_limit: int = proto.Field( + proto.INT64, + number=3, + ) + quota_minute_limit: int = proto.Field( + proto.INT64, + number=5, + ) + method_details: MutableSequence['MethodDetails'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='MethodDetails', + ) + + +class MethodDetails(proto.Message): + r"""The method details per method in the Merchant API. + + Attributes: + method (str): + Output only. The name of the method for example + ``products.list``. + version (str): + Output only. The API version that the method + belongs to. + subapi (str): + Output only. The sub-API that the method + belongs to. + path (str): + Output only. The path for the method such as + ``products/v1/productInputs.insert`` + """ + + method: str = proto.Field( + proto.STRING, + number=1, + ) + version: str = proto.Field( + proto.STRING, + number=2, + ) + subapi: str = proto.Field( + proto.STRING, + number=3, + ) + path: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ListQuotaGroupsRequest(proto.Message): + r"""Request message for the ListQuotaGroups method. + + Attributes: + parent (str): + Required. The merchant account who owns the + collection of method quotas Format: + accounts/{account} + page_size (int): + Optional. The maximum number of quotas to + return in the response, used for paging. + Defaults to 500; values above 1000 will be + coerced to 1000. + page_token (str): + Optional. Token (if provided) to retrieve the + subsequent page. All other parameters must match + the original call that provided the page token. + """ + + 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 ListQuotaGroupsResponse(proto.Message): + r"""Response message for the ListMethodGroups method. + + Attributes: + quota_groups (MutableSequence[google.shopping.merchant_quota_v1beta.types.QuotaGroup]): + The methods, current quota usage and limits per each group. + The quota is shared between all methods in the group. The + groups are sorted in descending order based on + [quotaUsage][google.shopping.merchant.quota.v1main.QuotaGroup.quota_usage]. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + quota_groups: MutableSequence['QuotaGroup'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='QuotaGroup', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/mypy.ini b/owl-bot-staging/google-shopping-merchant-quota/v1beta/mypy.ini new file mode 100644 index 000000000000..574c5aed394b --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/noxfile.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/noxfile.py new file mode 100644 index 000000000000..ab60f2f71caf --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/noxfile.py @@ -0,0 +1,280 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 re +import shutil +import subprocess +import sys + + +import nox # type: ignore + +ALL_PYTHON = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", +] + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = 'google-shopping-merchant-quota' + +BLACK_VERSION = "black==22.3.0" +BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] +DEFAULT_PYTHON_VERSION = "3.13" + +nox.sessions = [ + "unit", + "cover", + "mypy", + "check_lower_bounds" + # exclude update_lower_bounds from default + "docs", + "blacken", + "lint", + "prerelease_deps", +] + +@nox.session(python=ALL_PYTHON) +@nox.parametrize( + "protobuf_implementation", + [ "python", "upb", "cpp" ], +) +def unit(session, protobuf_implementation): + """Run the unit test suite.""" + + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + session.skip("cpp implementation is not supported in python 3.11+") + + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + session.install('-e', '.', "-c", f"testing/constraints-{session.python}.txt") + + # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. + # The 'cpp' implementation requires Protobuf<4. + if protobuf_implementation == "cpp": + session.install("protobuf<4") + + session.run( + 'py.test', + '--quiet', + '--cov=google/shopping/merchant_quota_v1beta/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)), + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + +@nox.session(python=ALL_PYTHON[-1]) +@nox.parametrize( + "protobuf_implementation", + [ "python", "upb", "cpp" ], +) +def prerelease_deps(session, protobuf_implementation): + """Run the unit test suite against pre-release versions of dependencies.""" + + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + session.skip("cpp implementation is not supported in python 3.11+") + + # Install test environment dependencies + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + + # Install the package without dependencies + session.install('-e', '.', '--no-deps') + + # We test the minimum dependency versions using the minimum Python + # version so the lowest python runtime that we test has a corresponding constraints + # file, located at `testing/constraints--.txt`, which contains all of the + # dependencies and extras. + with open( + CURRENT_DIRECTORY + / "testing" + / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + session.install(*constraints_deps) + + prerel_deps = [ + "googleapis-common-protos", + "google-api-core", + "google-auth", + # Exclude grpcio!=1.67.0rc1 which does not support python 3.13 + "grpcio!=1.67.0rc1", + "grpcio-status", + "protobuf", + "proto-plus", + ] + + for dep in prerel_deps: + session.install("--pre", "--no-deps", "--upgrade", dep) + + # Remaining dependencies + other_deps = [ + "requests", + ] + session.install(*other_deps) + + # Print out prerelease package versions + + session.run("python", "-c", "import google.api_core; print(google.api_core.__version__)") + session.run("python", "-c", "import google.auth; print(google.auth.__version__)") + session.run("python", "-c", "import grpc; print(grpc.__version__)") + session.run( + "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" + ) + session.run( + "python", "-c", "import proto; print(proto.__version__)" + ) + + session.run( + 'py.test', + '--quiet', + '--cov=google/shopping/merchant_quota_v1beta/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)), + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +@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', + '-p', + '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, + ) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_async.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_async.py new file mode 100644 index 000000000000..9df3fdc41d00 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListQuotaGroups +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-shopping-merchant-quota + + +# [START merchantapi_v1beta_generated_QuotaService_ListQuotaGroups_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.shopping import merchant_quota_v1beta + + +async def sample_list_quota_groups(): + # Create a client + client = merchant_quota_v1beta.QuotaServiceAsyncClient() + + # Initialize request argument(s) + request = merchant_quota_v1beta.ListQuotaGroupsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_quota_groups(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END merchantapi_v1beta_generated_QuotaService_ListQuotaGroups_async] diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_sync.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_sync.py new file mode 100644 index 000000000000..9cb0fe36a759 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListQuotaGroups +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-shopping-merchant-quota + + +# [START merchantapi_v1beta_generated_QuotaService_ListQuotaGroups_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.shopping import merchant_quota_v1beta + + +def sample_list_quota_groups(): + # Create a client + client = merchant_quota_v1beta.QuotaServiceClient() + + # Initialize request argument(s) + request = merchant_quota_v1beta.ListQuotaGroupsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_quota_groups(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END merchantapi_v1beta_generated_QuotaService_ListQuotaGroups_sync] diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1beta.json b/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1beta.json new file mode 100644 index 000000000000..884c8d108671 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1beta.json @@ -0,0 +1,176 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.shopping.merchant.quota.v1beta", + "version": "v1beta" + } + ], + "language": "PYTHON", + "name": "google-shopping-merchant-quota", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.shopping.merchant_quota_v1beta.QuotaServiceAsyncClient", + "shortName": "QuotaServiceAsyncClient" + }, + "fullName": "google.shopping.merchant_quota_v1beta.QuotaServiceAsyncClient.list_quota_groups", + "method": { + "fullName": "google.shopping.merchant.quota.v1beta.QuotaService.ListQuotaGroups", + "service": { + "fullName": "google.shopping.merchant.quota.v1beta.QuotaService", + "shortName": "QuotaService" + }, + "shortName": "ListQuotaGroups" + }, + "parameters": [ + { + "name": "request", + "type": "google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsRequest" + }, + { + "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.shopping.merchant_quota_v1beta.services.quota_service.pagers.ListQuotaGroupsAsyncPager", + "shortName": "list_quota_groups" + }, + "description": "Sample for ListQuotaGroups", + "file": "merchantapi_v1beta_generated_quota_service_list_quota_groups_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "merchantapi_v1beta_generated_QuotaService_ListQuotaGroups_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": "merchantapi_v1beta_generated_quota_service_list_quota_groups_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.shopping.merchant_quota_v1beta.QuotaServiceClient", + "shortName": "QuotaServiceClient" + }, + "fullName": "google.shopping.merchant_quota_v1beta.QuotaServiceClient.list_quota_groups", + "method": { + "fullName": "google.shopping.merchant.quota.v1beta.QuotaService.ListQuotaGroups", + "service": { + "fullName": "google.shopping.merchant.quota.v1beta.QuotaService", + "shortName": "QuotaService" + }, + "shortName": "ListQuotaGroups" + }, + "parameters": [ + { + "name": "request", + "type": "google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsRequest" + }, + { + "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.shopping.merchant_quota_v1beta.services.quota_service.pagers.ListQuotaGroupsPager", + "shortName": "list_quota_groups" + }, + "description": "Sample for ListQuotaGroups", + "file": "merchantapi_v1beta_generated_quota_service_list_quota_groups_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "merchantapi_v1beta_generated_QuotaService_ListQuotaGroups_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": "merchantapi_v1beta_generated_quota_service_list_quota_groups_sync.py" + } + ] +} diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/scripts/fixup_merchant_quota_v1beta_keywords.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/scripts/fixup_merchant_quota_v1beta_keywords.py new file mode 100644 index 000000000000..46854d66644a --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/scripts/fixup_merchant_quota_v1beta_keywords.py @@ -0,0 +1,176 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 merchant_quotaCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'list_quota_groups': ('parent', 'page_size', 'page_token', ), + } + + 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=merchant_quotaCallTransformer(), +): + """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 merchant_quota 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/google-shopping-merchant-quota/v1beta/setup.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/setup.py new file mode 100644 index 000000000000..29c7175c3c3a --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/setup.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 re + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = 'google-shopping-merchant-quota' + + +description = "Google Shopping Merchant Quota API client library" + +version = None + +with open(os.path.join(package_root, 'google/shopping/merchant_quota/gapic_version.py')) as fp: + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + assert (len(version_candidates) == 1) + version = version_candidates[0] + +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.1, <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.*", + # Exclude incompatible versions of `google-auth` + # See https://github.com/googleapis/google-cloud-python/issues/12364 + "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", + "proto-plus >= 1.22.3, <2.0.0dev", + "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", + "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", +] +extras = { +} +url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-quota" + +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.find_namespace_packages() + if package.startswith("google") +] + +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", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + install_requires=dependencies, + extras_require=extras, + include_package_data=True, + zip_safe=False, +) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.10.txt b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.10.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/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/google-shopping-merchant-quota/v1beta/testing/constraints-3.11.txt b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.11.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/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/google-shopping-merchant-quota/v1beta/testing/constraints-3.12.txt b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.12.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/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/google-shopping-merchant-quota/v1beta/testing/constraints-3.13.txt b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.13.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.13.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/google-shopping-merchant-quota/v1beta/testing/constraints-3.7.txt b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.7.txt new file mode 100644 index 000000000000..fc812592b0ee --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.7.txt @@ -0,0 +1,10 @@ +# 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.1 +google-auth==2.14.1 +proto-plus==1.22.3 +protobuf==3.20.2 diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.8.txt b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.8.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/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/google-shopping-merchant-quota/v1beta/testing/constraints-3.9.txt b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.9.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/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/google-shopping-merchant-quota/v1beta/tests/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-quota/v1beta/tests/unit/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-quota/v1beta/tests/unit/gapic/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py new file mode 100644 index 000000000000..e7c65aed459a --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py @@ -0,0 +1,2403 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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, AsyncIterable +from google.protobuf import json_format +import json +import math +import pytest +from google.api_core import api_core_version +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 + +try: + from google.auth.aio import credentials as ga_credentials_async + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +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.api_core import retry as retries +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.shopping.merchant_quota_v1beta.services.quota_service import QuotaServiceAsyncClient +from google.shopping.merchant_quota_v1beta.services.quota_service import QuotaServiceClient +from google.shopping.merchant_quota_v1beta.services.quota_service import pagers +from google.shopping.merchant_quota_v1beta.services.quota_service import transports +from google.shopping.merchant_quota_v1beta.types import quota +import google.auth + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + +# 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 + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return "test.{UNIVERSE_DOMAIN}" if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) else client._DEFAULT_ENDPOINT_TEMPLATE + + +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 QuotaServiceClient._get_default_mtls_endpoint(None) is None + assert QuotaServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert QuotaServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert QuotaServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert QuotaServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert QuotaServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + +def test__read_environment_variables(): + assert QuotaServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert QuotaServiceClient._read_environment_variables() == (True, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert QuotaServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError) as excinfo: + QuotaServiceClient._read_environment_variables() + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert QuotaServiceClient._read_environment_variables() == (False, "never", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert QuotaServiceClient._read_environment_variables() == (False, "always", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert QuotaServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + QuotaServiceClient._read_environment_variables() + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert QuotaServiceClient._read_environment_variables() == (False, "auto", "foo.com") + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert QuotaServiceClient._get_client_cert_source(None, False) is None + assert QuotaServiceClient._get_client_cert_source(mock_provided_cert_source, False) is None + assert QuotaServiceClient._get_client_cert_source(mock_provided_cert_source, True) == mock_provided_cert_source + + 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_default_cert_source): + assert QuotaServiceClient._get_client_cert_source(None, True) is mock_default_cert_source + assert QuotaServiceClient._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source + +@mock.patch.object(QuotaServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceClient)) +@mock.patch.object(QuotaServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceAsyncClient)) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = QuotaServiceClient._DEFAULT_UNIVERSE + default_endpoint = QuotaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) + mock_universe = "bar.com" + mock_endpoint = QuotaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) + + assert QuotaServiceClient._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override + assert QuotaServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == QuotaServiceClient.DEFAULT_MTLS_ENDPOINT + assert QuotaServiceClient._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint + assert QuotaServiceClient._get_api_endpoint(None, None, default_universe, "always") == QuotaServiceClient.DEFAULT_MTLS_ENDPOINT + assert QuotaServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == QuotaServiceClient.DEFAULT_MTLS_ENDPOINT + assert QuotaServiceClient._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint + assert QuotaServiceClient._get_api_endpoint(None, None, default_universe, "never") == default_endpoint + + with pytest.raises(MutualTLSChannelError) as excinfo: + QuotaServiceClient._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto") + assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com." + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert QuotaServiceClient._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain + assert QuotaServiceClient._get_universe_domain(None, universe_domain_env) == universe_domain_env + assert QuotaServiceClient._get_universe_domain(None, None) == QuotaServiceClient._DEFAULT_UNIVERSE + + with pytest.raises(ValueError) as excinfo: + QuotaServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc"), + (QuotaServiceClient, transports.QuotaServiceRestTransport, "rest"), +]) +def test__validate_universe_domain(client_class, transport_class, transport_name): + client = client_class( + transport=transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + ) + assert client._validate_universe_domain() == True + + # Test the case when universe is already validated. + assert client._validate_universe_domain() == True + + if transport_name == "grpc": + # Test the case where credentials are provided by the + # `local_channel_credentials`. The default universes in both match. + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + client = client_class(transport=transport_class(channel=channel)) + assert client._validate_universe_domain() == True + + # Test the case where credentials do not exist: e.g. a transport is provided + # with no credentials. Validation should still succeed because there is no + # mismatch with non-existent credentials. + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + transport=transport_class(channel=channel) + transport._credentials = None + client = client_class(transport=transport) + assert client._validate_universe_domain() == True + + # TODO: This is needed to cater for older versions of google-auth + # Make this test unconditional once the minimum supported version of + # google-auth becomes 2.23.0 or higher. + google_auth_major, google_auth_minor = [int(part) for part in google.auth.__version__.split(".")[0:2]] + if google_auth_major > 2 or (google_auth_major == 2 and google_auth_minor >= 23): + credentials = ga_credentials.AnonymousCredentials() + credentials._universe_domain = "foo.com" + # Test the case when there is a universe mismatch from the credentials. + client = client_class( + transport=transport_class(credentials=credentials) + ) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert str(excinfo.value) == "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (foo.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + + # Test the case when there is a universe mismatch from the client. + # + # TODO: Make this test unconditional once the minimum supported version of + # google-api-core becomes 2.15.0 or higher. + api_core_major, api_core_minor = [int(part) for part in api_core_version.__version__.split(".")[0:2]] + if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 15): + client = client_class(client_options={"universe_domain": "bar.com"}, transport=transport_class(credentials=ga_credentials.AnonymousCredentials(),)) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert str(excinfo.value) == "The configured universe domain (bar.com) does not match the universe domain found in the credentials (googleapis.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + + # Test that ValueError is raised if universe_domain is provided via client options and credentials is None + with pytest.raises(ValueError): + client._compare_universes("foo.bar", None) + + +@pytest.mark.parametrize("client_class,transport_name", [ + (QuotaServiceClient, "grpc"), + (QuotaServiceAsyncClient, "grpc_asyncio"), + (QuotaServiceClient, "rest"), +]) +def test_quota_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 == ( + 'merchantapi.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://merchantapi.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.QuotaServiceGrpcTransport, "grpc"), + (transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.QuotaServiceRestTransport, "rest"), +]) +def test_quota_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", [ + (QuotaServiceClient, "grpc"), + (QuotaServiceAsyncClient, "grpc_asyncio"), + (QuotaServiceClient, "rest"), +]) +def test_quota_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 == ( + 'merchantapi.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://merchantapi.googleapis.com' + ) + + +def test_quota_service_client_get_transport_class(): + transport = QuotaServiceClient.get_transport_class() + available_transports = [ + transports.QuotaServiceGrpcTransport, + transports.QuotaServiceRestTransport, + ] + assert transport in available_transports + + transport = QuotaServiceClient.get_transport_class("grpc") + assert transport == transports.QuotaServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc"), + (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (QuotaServiceClient, transports.QuotaServiceRestTransport, "rest"), +]) +@mock.patch.object(QuotaServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceClient)) +@mock.patch.object(QuotaServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceAsyncClient)) +def test_quota_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(QuotaServiceClient, '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(QuotaServiceClient, '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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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) as excinfo: + client = client_class(transport=transport_name) + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + # 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) as excinfo: + client = client_class(transport=transport_name) + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + + # 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + 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", [ + (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc", "true"), + (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc", "false"), + (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (QuotaServiceClient, transports.QuotaServiceRestTransport, "rest", "true"), + (QuotaServiceClient, transports.QuotaServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(QuotaServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceClient)) +@mock.patch.object(QuotaServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_quota_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) + 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) + 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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", [ + QuotaServiceClient, QuotaServiceAsyncClient +]) +@mock.patch.object(QuotaServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(QuotaServiceClient)) +@mock.patch.object(QuotaServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(QuotaServiceAsyncClient)) +def test_quota_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 + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + +@pytest.mark.parametrize("client_class", [ + QuotaServiceClient, QuotaServiceAsyncClient +]) +@mock.patch.object(QuotaServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceClient)) +@mock.patch.object(QuotaServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceAsyncClient)) +def test_quota_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = QuotaServiceClient._DEFAULT_UNIVERSE + default_endpoint = QuotaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) + mock_universe = "bar.com" + mock_endpoint = QuotaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel"): + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=api_override) + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + else: + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == (mock_endpoint if universe_exists else default_endpoint) + assert client.universe_domain == (mock_universe if universe_exists else default_universe) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc"), + (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (QuotaServiceClient, transports.QuotaServiceRestTransport, "rest"), +]) +def test_quota_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + 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", [ + (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc", grpc_helpers), + (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (QuotaServiceClient, transports.QuotaServiceRestTransport, "rest", None), +]) +def test_quota_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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_quota_service_client_client_options_from_dict(): + with mock.patch('google.shopping.merchant_quota_v1beta.services.quota_service.transports.QuotaServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = QuotaServiceClient( + 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", [ + (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc", grpc_helpers), + (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_quota_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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( + "merchantapi.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/content', +), + scopes=None, + default_host="merchantapi.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + quota.ListQuotaGroupsRequest, + dict, +]) +def test_list_quota_groups(request_type, transport: str = 'grpc'): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_quota_groups), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = quota.ListQuotaGroupsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_quota_groups(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = quota.ListQuotaGroupsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListQuotaGroupsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_quota_groups_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = quota.ListQuotaGroupsRequest( + parent='parent_value', + page_token='page_token_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_quota_groups), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.list_quota_groups(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == quota.ListQuotaGroupsRequest( + parent='parent_value', + page_token='page_token_value', + ) + +def test_list_quota_groups_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_quota_groups in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.list_quota_groups] = mock_rpc + request = {} + client.list_quota_groups(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_quota_groups(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_quota_groups_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = QuotaServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.list_quota_groups in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.list_quota_groups] = mock_rpc + + request = {} + await client.list_quota_groups(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_quota_groups(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_quota_groups_async(transport: str = 'grpc_asyncio', request_type=quota.ListQuotaGroupsRequest): + client = QuotaServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_quota_groups), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(quota.ListQuotaGroupsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_quota_groups(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = quota.ListQuotaGroupsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListQuotaGroupsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_quota_groups_async_from_dict(): + await test_list_quota_groups_async(request_type=dict) + +def test_list_quota_groups_field_headers(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = quota.ListQuotaGroupsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_quota_groups), + '__call__') as call: + call.return_value = quota.ListQuotaGroupsResponse() + client.list_quota_groups(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_quota_groups_field_headers_async(): + client = QuotaServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = quota.ListQuotaGroupsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_quota_groups), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(quota.ListQuotaGroupsResponse()) + await client.list_quota_groups(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_quota_groups_flattened(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_quota_groups), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = quota.ListQuotaGroupsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_quota_groups( + 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_quota_groups_flattened_error(): + client = QuotaServiceClient( + 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_quota_groups( + quota.ListQuotaGroupsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_quota_groups_flattened_async(): + client = QuotaServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_quota_groups), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = quota.ListQuotaGroupsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(quota.ListQuotaGroupsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_quota_groups( + 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_quota_groups_flattened_error_async(): + client = QuotaServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_quota_groups( + quota.ListQuotaGroupsRequest(), + parent='parent_value', + ) + + +def test_list_quota_groups_pager(transport_name: str = "grpc"): + client = QuotaServiceClient( + 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_quota_groups), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + quota.QuotaGroup(), + quota.QuotaGroup(), + ], + next_page_token='abc', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[], + next_page_token='def', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + ], + next_page_token='ghi', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + quota.QuotaGroup(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_quota_groups(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, quota.QuotaGroup) + for i in results) +def test_list_quota_groups_pages(transport_name: str = "grpc"): + client = QuotaServiceClient( + 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_quota_groups), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + quota.QuotaGroup(), + quota.QuotaGroup(), + ], + next_page_token='abc', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[], + next_page_token='def', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + ], + next_page_token='ghi', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + quota.QuotaGroup(), + ], + ), + RuntimeError, + ) + pages = list(client.list_quota_groups(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_quota_groups_async_pager(): + client = QuotaServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_quota_groups), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + quota.QuotaGroup(), + quota.QuotaGroup(), + ], + next_page_token='abc', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[], + next_page_token='def', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + ], + next_page_token='ghi', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + quota.QuotaGroup(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_quota_groups(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, quota.QuotaGroup) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_quota_groups_async_pages(): + client = QuotaServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_quota_groups), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + quota.QuotaGroup(), + quota.QuotaGroup(), + ], + next_page_token='abc', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[], + next_page_token='def', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + ], + next_page_token='ghi', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + quota.QuotaGroup(), + ], + ), + 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_quota_groups(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_list_quota_groups_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_quota_groups in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.list_quota_groups] = mock_rpc + + request = {} + client.list_quota_groups(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_quota_groups(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_quota_groups_rest_required_fields(request_type=quota.ListQuotaGroupsRequest): + transport_class = transports.QuotaServiceRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_quota_groups._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_quota_groups._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 = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = quota.ListQuotaGroupsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = quota.ListQuotaGroupsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_quota_groups(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_quota_groups_rest_unset_required_fields(): + transport = transports.QuotaServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_quota_groups._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +def test_list_quota_groups_rest_flattened(): + client = QuotaServiceClient( + 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 = quota.ListQuotaGroupsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'accounts/sample1'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = quota.ListQuotaGroupsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_quota_groups(**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/quota/v1beta/{parent=accounts/*}/quotas" % client.transport._host, args[1]) + + +def test_list_quota_groups_rest_flattened_error(transport: str = 'rest'): + client = QuotaServiceClient( + 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_quota_groups( + quota.ListQuotaGroupsRequest(), + parent='parent_value', + ) + + +def test_list_quota_groups_rest_pager(transport: str = 'rest'): + client = QuotaServiceClient( + 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 = ( + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + quota.QuotaGroup(), + quota.QuotaGroup(), + ], + next_page_token='abc', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[], + next_page_token='def', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + ], + next_page_token='ghi', + ), + quota.ListQuotaGroupsResponse( + quota_groups=[ + quota.QuotaGroup(), + quota.QuotaGroup(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(quota.ListQuotaGroupsResponse.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': 'accounts/sample1'} + + pager = client.list_quota_groups(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, quota.QuotaGroup) + for i in results) + + pages = list(client.list_quota_groups(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.QuotaServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.QuotaServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = QuotaServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.QuotaServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = QuotaServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = QuotaServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.QuotaServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = QuotaServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.QuotaServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = QuotaServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.QuotaServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.QuotaServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.QuotaServiceGrpcTransport, + transports.QuotaServiceGrpcAsyncIOTransport, + transports.QuotaServiceRestTransport, +]) +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() + +def test_transport_kind_grpc(): + transport = QuotaServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_quota_groups_empty_call_grpc(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_quota_groups), + '__call__') as call: + call.return_value = quota.ListQuotaGroupsResponse() + client.list_quota_groups(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = quota.ListQuotaGroupsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = QuotaServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = QuotaServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_quota_groups_empty_call_grpc_asyncio(): + client = QuotaServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_quota_groups), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(quota.ListQuotaGroupsResponse( + next_page_token='next_page_token_value', + )) + await client.list_quota_groups(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = quota.ListQuotaGroupsRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = QuotaServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_list_quota_groups_rest_bad_request(request_type=quota.ListQuotaGroupsRequest): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'parent': 'accounts/sample1'} + 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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_quota_groups(request) + + +@pytest.mark.parametrize("request_type", [ + quota.ListQuotaGroupsRequest, + dict, +]) +def test_list_quota_groups_rest_call_success(request_type): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'accounts/sample1'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = quota.ListQuotaGroupsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = quota.ListQuotaGroupsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_quota_groups(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListQuotaGroupsPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_quota_groups_rest_interceptors(null_interceptor): + transport = transports.QuotaServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.QuotaServiceRestInterceptor(), + ) + client = QuotaServiceClient(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.QuotaServiceRestInterceptor, "post_list_quota_groups") as post, \ + mock.patch.object(transports.QuotaServiceRestInterceptor, "pre_list_quota_groups") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = quota.ListQuotaGroupsRequest.pb(quota.ListQuotaGroupsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = quota.ListQuotaGroupsResponse.to_json(quota.ListQuotaGroupsResponse()) + req.return_value.content = return_value + + request = quota.ListQuotaGroupsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = quota.ListQuotaGroupsResponse() + + client.list_quota_groups(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + +def test_initialize_client_w_rest(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_quota_groups_empty_call_rest(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_quota_groups), + '__call__') as call: + client.list_quota_groups(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = quota.ListQuotaGroupsRequest() + + assert args[0] == request_msg + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.QuotaServiceGrpcTransport, + ) + +def test_quota_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.QuotaServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_quota_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.shopping.merchant_quota_v1beta.services.quota_service.transports.QuotaServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.QuotaServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'list_quota_groups', + ) + 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_quota_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.shopping.merchant_quota_v1beta.services.quota_service.transports.QuotaServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.QuotaServiceTransport( + 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/content', +), + quota_project_id="octopus", + ) + + +def test_quota_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.shopping.merchant_quota_v1beta.services.quota_service.transports.QuotaServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.QuotaServiceTransport() + adc.assert_called_once() + + +def test_quota_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) + QuotaServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/content', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.QuotaServiceGrpcTransport, + transports.QuotaServiceGrpcAsyncIOTransport, + ], +) +def test_quota_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/content',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.QuotaServiceGrpcTransport, + transports.QuotaServiceGrpcAsyncIOTransport, + transports.QuotaServiceRestTransport, + ], +) +def test_quota_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.QuotaServiceGrpcTransport, grpc_helpers), + (transports.QuotaServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_quota_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( + "merchantapi.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/content', +), + scopes=["1", "2"], + default_host="merchantapi.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.QuotaServiceGrpcTransport, transports.QuotaServiceGrpcAsyncIOTransport]) +def test_quota_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_quota_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.QuotaServiceRestTransport ( + 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_quota_service_host_no_port(transport_name): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='merchantapi.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'merchantapi.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://merchantapi.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_quota_service_host_with_port(transport_name): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='merchantapi.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'merchantapi.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://merchantapi.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_quota_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = QuotaServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = QuotaServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.list_quota_groups._session + session2 = client2.transport.list_quota_groups._session + assert session1 != session2 +def test_quota_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.QuotaServiceGrpcTransport( + 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_quota_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.QuotaServiceGrpcAsyncIOTransport( + 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.QuotaServiceGrpcTransport, transports.QuotaServiceGrpcAsyncIOTransport]) +def test_quota_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.QuotaServiceGrpcTransport, transports.QuotaServiceGrpcAsyncIOTransport]) +def test_quota_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_quota_group_path(): + account = "squid" + group = "clam" + expected = "accounts/{account}/groups/{group}".format(account=account, group=group, ) + actual = QuotaServiceClient.quota_group_path(account, group) + assert expected == actual + + +def test_parse_quota_group_path(): + expected = { + "account": "whelk", + "group": "octopus", + } + path = QuotaServiceClient.quota_group_path(**expected) + + # Check that the path construction is reversible. + actual = QuotaServiceClient.parse_quota_group_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "oyster" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = QuotaServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nudibranch", + } + path = QuotaServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = QuotaServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "cuttlefish" + expected = "folders/{folder}".format(folder=folder, ) + actual = QuotaServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "mussel", + } + path = QuotaServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = QuotaServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "winkle" + expected = "organizations/{organization}".format(organization=organization, ) + actual = QuotaServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nautilus", + } + path = QuotaServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = QuotaServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "scallop" + expected = "projects/{project}".format(project=project, ) + actual = QuotaServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "abalone", + } + path = QuotaServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = QuotaServiceClient.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 = QuotaServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "whelk", + "location": "octopus", + } + path = QuotaServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = QuotaServiceClient.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.QuotaServiceTransport, '_prep_wrapped_messages') as prep: + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.QuotaServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = QuotaServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_grpc(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc" + ) + with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = QuotaServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio" + ) + with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close_rest(): + client = QuotaServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + with mock.patch.object(type(getattr(client.transport, "_session")), "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 = QuotaServiceClient( + 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", [ + (QuotaServiceClient, transports.QuotaServiceGrpcTransport), + (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport), +]) +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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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/google-shopping-merchant-reports/v1beta/.coveragerc b/owl-bot-staging/google-shopping-merchant-reports/v1beta/.coveragerc new file mode 100644 index 000000000000..ee0fc2257adb --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/shopping/merchant_reports/__init__.py + google/shopping/merchant_reports/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/google-shopping-merchant-reports/v1beta/.flake8 b/owl-bot-staging/google-shopping-merchant-reports/v1beta/.flake8 new file mode 100644 index 000000000000..29227d4cf419 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/.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/google-shopping-merchant-reports/v1beta/MANIFEST.in b/owl-bot-staging/google-shopping-merchant-reports/v1beta/MANIFEST.in new file mode 100644 index 000000000000..baaee74264b4 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include google/shopping/merchant_reports *.py +recursive-include google/shopping/merchant_reports_v1beta *.py diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/README.rst b/owl-bot-staging/google-shopping-merchant-reports/v1beta/README.rst new file mode 100644 index 000000000000..33f7f87a7a6c --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/README.rst @@ -0,0 +1,49 @@ +Python Client for Google Shopping Merchant Reports 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 Shopping Merchant Reports 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/google-shopping-merchant-reports/v1beta/docs/_static/custom.css b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/_static/custom.css new file mode 100644 index 000000000000..06423be0b592 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/_static/custom.css @@ -0,0 +1,3 @@ +dl.field-list > dt { + min-width: 100px +} diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/conf.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/conf.py new file mode 100644 index 000000000000..e082f6d42016 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/conf.py @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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-shopping-merchant-reports 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-shopping-merchant-reports" +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 Shopping 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-shopping-merchant-reports-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-shopping-merchant-reports.tex", + u"google-shopping-merchant-reports 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-shopping-merchant-reports", + u"Google Shopping Merchant Reports 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-shopping-merchant-reports", + u"google-shopping-merchant-reports Documentation", + author, + "google-shopping-merchant-reports", + "GAPIC library for Google Shopping Merchant Reports 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/google-shopping-merchant-reports/v1beta/docs/index.rst b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/index.rst new file mode 100644 index 000000000000..56b119bc9a3d --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + merchant_reports_v1beta/services_ + merchant_reports_v1beta/types_ diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/report_service.rst b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/report_service.rst new file mode 100644 index 000000000000..38d2a647339e --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/report_service.rst @@ -0,0 +1,10 @@ +ReportService +------------------------------- + +.. automodule:: google.shopping.merchant_reports_v1beta.services.report_service + :members: + :inherited-members: + +.. automodule:: google.shopping.merchant_reports_v1beta.services.report_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/services_.rst b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/services_.rst new file mode 100644 index 000000000000..55109976f640 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/services_.rst @@ -0,0 +1,6 @@ +Services for Google Shopping Merchant Reports v1beta API +======================================================== +.. toctree:: + :maxdepth: 2 + + report_service diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/types_.rst b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/types_.rst new file mode 100644 index 000000000000..3f9d6a921dbd --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/types_.rst @@ -0,0 +1,6 @@ +Types for Google Shopping Merchant Reports v1beta API +===================================================== + +.. automodule:: google.shopping.merchant_reports_v1beta.types + :members: + :show-inheritance: diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/__init__.py new file mode 100644 index 000000000000..9a1854b53a00 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/__init__.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.shopping.merchant_reports import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.shopping.merchant_reports_v1beta.services.report_service.client import ReportServiceClient +from google.shopping.merchant_reports_v1beta.services.report_service.async_client import ReportServiceAsyncClient + +from google.shopping.merchant_reports_v1beta.types.reports import BestSellersBrandView +from google.shopping.merchant_reports_v1beta.types.reports import BestSellersProductClusterView +from google.shopping.merchant_reports_v1beta.types.reports import CompetitiveVisibilityBenchmarkView +from google.shopping.merchant_reports_v1beta.types.reports import CompetitiveVisibilityCompetitorView +from google.shopping.merchant_reports_v1beta.types.reports import CompetitiveVisibilityTopMerchantView +from google.shopping.merchant_reports_v1beta.types.reports import MarketingMethod +from google.shopping.merchant_reports_v1beta.types.reports import NonProductPerformanceView +from google.shopping.merchant_reports_v1beta.types.reports import PriceCompetitivenessProductView +from google.shopping.merchant_reports_v1beta.types.reports import PriceInsightsProductView +from google.shopping.merchant_reports_v1beta.types.reports import ProductPerformanceView +from google.shopping.merchant_reports_v1beta.types.reports import ProductView +from google.shopping.merchant_reports_v1beta.types.reports import RelativeDemand +from google.shopping.merchant_reports_v1beta.types.reports import RelativeDemandChangeType +from google.shopping.merchant_reports_v1beta.types.reports import ReportGranularity +from google.shopping.merchant_reports_v1beta.types.reports import ReportRow +from google.shopping.merchant_reports_v1beta.types.reports import SearchRequest +from google.shopping.merchant_reports_v1beta.types.reports import SearchResponse +from google.shopping.merchant_reports_v1beta.types.reports import TrafficSource + +__all__ = ('ReportServiceClient', + 'ReportServiceAsyncClient', + 'BestSellersBrandView', + 'BestSellersProductClusterView', + 'CompetitiveVisibilityBenchmarkView', + 'CompetitiveVisibilityCompetitorView', + 'CompetitiveVisibilityTopMerchantView', + 'MarketingMethod', + 'NonProductPerformanceView', + 'PriceCompetitivenessProductView', + 'PriceInsightsProductView', + 'ProductPerformanceView', + 'ProductView', + 'RelativeDemand', + 'RelativeDemandChangeType', + 'ReportGranularity', + 'ReportRow', + 'SearchRequest', + 'SearchResponse', + 'TrafficSource', +) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/gapic_version.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/gapic_version.py new file mode 100644 index 000000000000..558c8aab67c5 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/py.typed b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/py.typed new file mode 100644 index 000000000000..925c5df4dab6 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-shopping-merchant-reports package uses inline types. diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/__init__.py new file mode 100644 index 000000000000..3f709e1477bb --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/__init__.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.shopping.merchant_reports_v1beta import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.report_service import ReportServiceClient +from .services.report_service import ReportServiceAsyncClient + +from .types.reports import BestSellersBrandView +from .types.reports import BestSellersProductClusterView +from .types.reports import CompetitiveVisibilityBenchmarkView +from .types.reports import CompetitiveVisibilityCompetitorView +from .types.reports import CompetitiveVisibilityTopMerchantView +from .types.reports import MarketingMethod +from .types.reports import NonProductPerformanceView +from .types.reports import PriceCompetitivenessProductView +from .types.reports import PriceInsightsProductView +from .types.reports import ProductPerformanceView +from .types.reports import ProductView +from .types.reports import RelativeDemand +from .types.reports import RelativeDemandChangeType +from .types.reports import ReportGranularity +from .types.reports import ReportRow +from .types.reports import SearchRequest +from .types.reports import SearchResponse +from .types.reports import TrafficSource + +__all__ = ( + 'ReportServiceAsyncClient', +'BestSellersBrandView', +'BestSellersProductClusterView', +'CompetitiveVisibilityBenchmarkView', +'CompetitiveVisibilityCompetitorView', +'CompetitiveVisibilityTopMerchantView', +'MarketingMethod', +'NonProductPerformanceView', +'PriceCompetitivenessProductView', +'PriceInsightsProductView', +'ProductPerformanceView', +'ProductView', +'RelativeDemand', +'RelativeDemandChangeType', +'ReportGranularity', +'ReportRow', +'ReportServiceClient', +'SearchRequest', +'SearchResponse', +'TrafficSource', +) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_metadata.json b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_metadata.json new file mode 100644 index 000000000000..77c560dce3aa --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_metadata.json @@ -0,0 +1,43 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.shopping.merchant_reports_v1beta", + "protoPackage": "google.shopping.merchant.reports.v1beta", + "schema": "1.0", + "services": { + "ReportService": { + "clients": { + "grpc": { + "libraryClient": "ReportServiceClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ReportServiceAsyncClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + }, + "rest": { + "libraryClient": "ReportServiceClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + } + } + } + } +} diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_version.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_version.py new file mode 100644 index 000000000000..558c8aab67c5 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/py.typed b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/py.typed new file mode 100644 index 000000000000..925c5df4dab6 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-shopping-merchant-reports package uses inline types. diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/__init__.py new file mode 100644 index 000000000000..8f6cf068242c --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/__init__.py new file mode 100644 index 000000000000..90845062383d --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ReportServiceClient +from .async_client import ReportServiceAsyncClient + +__all__ = ( + 'ReportServiceClient', + 'ReportServiceAsyncClient', +) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/async_client.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/async_client.py new file mode 100644 index 000000000000..30efef354296 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/async_client.py @@ -0,0 +1,361 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 re +from typing import Dict, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.shopping.merchant_reports_v1beta 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_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.shopping.merchant_reports_v1beta.services.report_service import pagers +from google.shopping.merchant_reports_v1beta.types import reports +from .transports.base import ReportServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ReportServiceGrpcAsyncIOTransport +from .client import ReportServiceClient + + +class ReportServiceAsyncClient: + """Service for retrieving reports and insights about your + products, their performance, and their competitive environment + on Google. + """ + + _client: ReportServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ReportServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ReportServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ReportServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = ReportServiceClient._DEFAULT_UNIVERSE + + common_billing_account_path = staticmethod(ReportServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ReportServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ReportServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ReportServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ReportServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ReportServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ReportServiceClient.common_project_path) + parse_common_project_path = staticmethod(ReportServiceClient.parse_common_project_path) + common_location_path = staticmethod(ReportServiceClient.common_location_path) + parse_common_location_path = staticmethod(ReportServiceClient.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: + ReportServiceAsyncClient: The constructed client. + """ + return ReportServiceClient.from_service_account_info.__func__(ReportServiceAsyncClient, 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: + ReportServiceAsyncClient: The constructed client. + """ + return ReportServiceClient.from_service_account_file.__func__(ReportServiceAsyncClient, 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 ReportServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ReportServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ReportServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ReportServiceClient.get_transport_class + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, ReportServiceTransport, Callable[..., ReportServiceTransport]]] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the report service async 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 (Optional[Union[str,ReportServiceTransport,Callable[..., ReportServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ReportServiceTransport constructor. + 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. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client = ReportServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def search(self, + request: Optional[Union[reports.SearchRequest, 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.SearchAsyncPager: + r"""Retrieves a report defined by a search query. The response might + contain fewer rows than specified by ``page_size``. Rely on + ``next_page_token`` to determine if there are more rows to be + requested. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.shopping import merchant_reports_v1beta + + async def sample_search(): + # Create a client + client = merchant_reports_v1beta.ReportServiceAsyncClient() + + # Initialize request argument(s) + request = merchant_reports_v1beta.SearchRequest( + parent="parent_value", + query="query_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.shopping.merchant_reports_v1beta.types.SearchRequest, dict]]): + The request object. Request message for the ``ReportService.Search`` method. + parent (:class:`str`): + Required. Id of the account making + the call. Must be a standalone account + or an MCA subaccount. Format: + accounts/{account} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.shopping.merchant_reports_v1beta.services.report_service.pagers.SearchAsyncPager: + Response message for the ReportService.Search 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.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, reports.SearchRequest): + request = reports.SearchRequest(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._client._transport._wrapped_methods[self._client._transport.search] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ReportServiceAsyncClient": + 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__ = ( + "ReportServiceAsyncClient", +) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/client.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/client.py new file mode 100644 index 000000000000..a61603b38fdf --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/client.py @@ -0,0 +1,708 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.shopping.merchant_reports_v1beta 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, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +from google.shopping.merchant_reports_v1beta.services.report_service import pagers +from google.shopping.merchant_reports_v1beta.types import reports +from .transports.base import ReportServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ReportServiceGrpcTransport +from .transports.grpc_asyncio import ReportServiceGrpcAsyncIOTransport +from .transports.rest import ReportServiceRestTransport + + +class ReportServiceClientMeta(type): + """Metaclass for the ReportService 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[ReportServiceTransport]] + _transport_registry["grpc"] = ReportServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ReportServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ReportServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ReportServiceTransport]: + """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 ReportServiceClient(metaclass=ReportServiceClientMeta): + """Service for retrieving reports and insights about your + products, their performance, and their competitive environment + on Google. + """ + + @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") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "merchantapi.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "merchantapi.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @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: + ReportServiceClient: 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: + ReportServiceClient: 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) -> ReportServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ReportServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path(billing_account: str, ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str,str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path(folder: str, ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format(folder=folder, ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str,str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path(organization: str, ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format(organization=organization, ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str,str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path(project: str, ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str,str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path(project: str, location: str, ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format(project=project, location=location, ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str,str]: + """Parse a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): + """Deprecated. 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. + """ + + warnings.warn("get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning) + 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 + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false").lower() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + 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`") + return use_client_cert == "true", use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint(api_override, client_cert_source, universe_domain, use_mtls_endpoint): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + _default_universe = ReportServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError(f"mTLS is not supported in any universe other than {_default_universe}.") + api_endpoint = ReportServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ReportServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=universe_domain) + return api_endpoint + + @staticmethod + def _get_universe_domain(client_universe_domain: Optional[str], universe_domain_env: Optional[str]) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ReportServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + @staticmethod + def _compare_universes(client_universe: str, + credentials: ga_credentials.Credentials) -> bool: + """Returns True iff the universe domains used by the client and credentials match. + + Args: + client_universe (str): The universe domain configured via the client options. + credentials (ga_credentials.Credentials): The credentials being used in the client. + + Returns: + bool: True iff client_universe matches the universe in credentials. + + Raises: + ValueError: when client_universe does not match the universe in credentials. + """ + + default_universe = ReportServiceClient._DEFAULT_UNIVERSE + credentials_universe = getattr(credentials, "universe_domain", default_universe) + + if client_universe != credentials_universe: + raise ValueError("The configured universe domain " + f"({client_universe}) does not match the universe domain " + f"found in the credentials ({credentials_universe}). " + "If you haven't configured the universe domain explicitly, " + f"`{default_universe}` is the default.") + return True + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + self._is_universe_domain_valid = (self._is_universe_domain_valid or + ReportServiceClient._compare_universes(self.universe_domain, self.transport._credentials)) + return self._is_universe_domain_valid + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, ReportServiceTransport, Callable[..., ReportServiceTransport]]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the report 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 (Optional[Union[str,ReportServiceTransport,Callable[..., ReportServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ReportServiceTransport constructor. + 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. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast(client_options_lib.ClientOptions, self._client_options) + + universe_domain_opt = getattr(self._client_options, 'universe_domain', None) + + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = ReportServiceClient._read_environment_variables() + self._client_cert_source = ReportServiceClient._get_client_cert_source(self._client_options.client_cert_source, self._use_client_cert) + self._universe_domain = ReportServiceClient._get_universe_domain(universe_domain_opt, self._universe_domain_env) + self._api_endpoint = None # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + api_key_value = getattr(self._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. + transport_provided = isinstance(transport, ReportServiceTransport) + if transport_provided: + # transport is a ReportServiceTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(ReportServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = (self._api_endpoint or + ReportServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint)) + + if not transport_provided: + 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_init: Union[Type[ReportServiceTransport], Callable[..., ReportServiceTransport]] = ( + ReportServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., ReportServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + def search(self, + request: Optional[Union[reports.SearchRequest, 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.SearchPager: + r"""Retrieves a report defined by a search query. The response might + contain fewer rows than specified by ``page_size``. Rely on + ``next_page_token`` to determine if there are more rows to be + requested. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.shopping import merchant_reports_v1beta + + def sample_search(): + # Create a client + client = merchant_reports_v1beta.ReportServiceClient() + + # Initialize request argument(s) + request = merchant_reports_v1beta.SearchRequest( + parent="parent_value", + query="query_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.shopping.merchant_reports_v1beta.types.SearchRequest, dict]): + The request object. Request message for the ``ReportService.Search`` method. + parent (str): + Required. Id of the account making + the call. Must be a standalone account + or an MCA subaccount. Format: + accounts/{account} + + 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.shopping.merchant_reports_v1beta.services.report_service.pagers.SearchPager: + Response message for the ReportService.Search 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.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, reports.SearchRequest): + request = reports.SearchRequest(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.search] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ReportServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ReportServiceClient", +) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/pagers.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/pagers.py new file mode 100644 index 000000000000..c69018f6bf97 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/pagers.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async +from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator, Union +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.shopping.merchant_reports_v1beta.types import reports + + +class SearchPager: + """A pager for iterating through ``search`` requests. + + This class thinly wraps an initial + :class:`google.shopping.merchant_reports_v1beta.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.shopping.merchant_reports_v1beta.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[..., reports.SearchResponse], + request: reports.SearchRequest, + response: reports.SearchResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.shopping.merchant_reports_v1beta.types.SearchRequest): + The initial request object. + response (google.shopping.merchant_reports_v1beta.types.SearchResponse): + The initial response object. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = reports.SearchRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[reports.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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[reports.ReportRow]: + 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.shopping.merchant_reports_v1beta.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.shopping.merchant_reports_v1beta.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[reports.SearchResponse]], + request: reports.SearchRequest, + response: reports.SearchResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.shopping.merchant_reports_v1beta.types.SearchRequest): + The initial request object. + response (google.shopping.merchant_reports_v1beta.types.SearchResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = reports.SearchRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[reports.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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[reports.ReportRow]: + 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/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/README.rst b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/README.rst new file mode 100644 index 000000000000..3ff494d6f149 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`ReportServiceTransport` is the ABC for all transports. +- public child `ReportServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `ReportServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseReportServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `ReportServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/__init__.py new file mode 100644 index 000000000000..a2d3480db148 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ReportServiceTransport +from .grpc import ReportServiceGrpcTransport +from .grpc_asyncio import ReportServiceGrpcAsyncIOTransport +from .rest import ReportServiceRestTransport +from .rest import ReportServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ReportServiceTransport]] +_transport_registry['grpc'] = ReportServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ReportServiceGrpcAsyncIOTransport +_transport_registry['rest'] = ReportServiceRestTransport + +__all__ = ( + 'ReportServiceTransport', + 'ReportServiceGrpcTransport', + 'ReportServiceGrpcAsyncIOTransport', + 'ReportServiceRestTransport', + 'ReportServiceRestInterceptor', +) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/base.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/base.py new file mode 100644 index 000000000000..93d8c8bff712 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/base.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.shopping.merchant_reports_v1beta 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.shopping.merchant_reports_v1beta.types import reports + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class ReportServiceTransport(abc.ABC): + """Abstract transport class for ReportService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/content', + ) + + DEFAULT_HOST: str = 'merchantapi.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 (default: 'merchantapi.googleapis.com'). + 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 not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # 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 and not self._ignore_credentials: + 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 + + @property + def host(self): + return self._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[ + [reports.SearchRequest], + Union[ + reports.SearchResponse, + Awaitable[reports.SearchResponse] + ]]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ReportServiceTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc.py new file mode 100644 index 000000000000..590b4dedd295 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc.py @@ -0,0 +1,275 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.shopping.merchant_reports_v1beta.types import reports +from .base import ReportServiceTransport, DEFAULT_CLIENT_INFO + + +class ReportServiceGrpcTransport(ReportServiceTransport): + """gRPC backend transport for ReportService. + + Service for retrieving reports and insights about your + products, their performance, and their competitive environment + on Google. + + 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 = 'merchantapi.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[grpc.Channel, Callable[..., 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 (default: 'merchantapi.googleapis.com'). + 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 a ``channel`` instance 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 a ``channel`` instance is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # 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: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + 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 = 'merchantapi.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[ + [reports.SearchRequest], + reports.SearchResponse]: + r"""Return a callable for the search method over gRPC. + + Retrieves a report defined by a search query. The response might + contain fewer rows than specified by ``page_size``. Rely on + ``next_page_token`` to determine if there are more rows to be + requested. + + 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.shopping.merchant.reports.v1beta.ReportService/Search', + request_serializer=reports.SearchRequest.serialize, + response_deserializer=reports.SearchResponse.deserialize, + ) + return self._stubs['search'] + + def close(self): + self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ReportServiceGrpcTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py new file mode 100644 index 000000000000..8aa8e5af0778 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py @@ -0,0 +1,296 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 inspect +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 exceptions as core_exceptions +from google.api_core import retry_async as retries +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.shopping.merchant_reports_v1beta.types import reports +from .base import ReportServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ReportServiceGrpcTransport + + +class ReportServiceGrpcAsyncIOTransport(ReportServiceTransport): + """gRPC AsyncIO backend transport for ReportService. + + Service for retrieving reports and insights about your + products, their performance, and their competitive environment + on Google. + + 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 = 'merchantapi.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`. + 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 = 'merchantapi.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[aio.Channel, Callable[..., 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 (default: 'merchantapi.googleapis.com'). + 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 a ``channel`` instance 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 a ``channel`` instance 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[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # 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: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + 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._wrap_with_kind = "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + 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[ + [reports.SearchRequest], + Awaitable[reports.SearchResponse]]: + r"""Return a callable for the search method over gRPC. + + Retrieves a report defined by a search query. The response might + contain fewer rows than specified by ``page_size``. Rely on + ``next_page_token`` to determine if there are more rows to be + requested. + + 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.shopping.merchant.reports.v1beta.ReportService/Search', + request_serializer=reports.SearchRequest.serialize, + response_deserializer=reports.SearchResponse.deserialize, + ) + return self._stubs['search'] + + def _prep_wrapped_messages(self, client_info): + """ Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.search: self._wrap_method( + self.search, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ( + 'ReportServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py new file mode 100644 index 000000000000..ed399060e330 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py @@ -0,0 +1,279 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 +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 gapic_v1 + +from google.protobuf import json_format + +from requests import __version__ as requests_version +import dataclasses +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + + +from google.shopping.merchant_reports_v1beta.types import reports + + +from .rest_base import _BaseReportServiceRestTransport +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + + +class ReportServiceRestInterceptor: + """Interceptor for ReportService. + + 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 ReportServiceRestTransport. + + .. code-block:: python + class MyCustomReportServiceInterceptor(ReportServiceRestInterceptor): + 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 = ReportServiceRestTransport(interceptor=MyCustomReportServiceInterceptor()) + client = ReportServiceClient(transport=transport) + + + """ + def pre_search(self, request: reports.SearchRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[reports.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 ReportService server. + """ + return request, metadata + + def post_search(self, response: reports.SearchResponse) -> reports.SearchResponse: + """Post-rpc interceptor for search + + Override in a subclass to manipulate the response + after it is returned by the ReportService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ReportServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ReportServiceRestInterceptor + + +class ReportServiceRestTransport(_BaseReportServiceRestTransport): + """REST backend synchronous transport for ReportService. + + Service for retrieving reports and insights about your + products, their performance, and their competitive environment + on Google. + + 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 = 'merchantapi.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[ReportServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + 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 + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + 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 ReportServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _Search(_BaseReportServiceRestTransport._BaseSearch, ReportServiceRestStub): + def __hash__(self): + return hash("ReportServiceRestTransport.Search") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__(self, + request: reports.SearchRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> reports.SearchResponse: + r"""Call the search method over HTTP. + + Args: + request (~.reports.SearchRequest): + The request object. Request message for the ``ReportService.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: + ~.reports.SearchResponse: + Response message for the ``ReportService.Search`` + method. + + """ + + http_options = _BaseReportServiceRestTransport._BaseSearch._get_http_options() + request, metadata = self._interceptor.pre_search(request, metadata) + transcoded_request = _BaseReportServiceRestTransport._BaseSearch._get_transcoded_request(http_options, request) + + body = _BaseReportServiceRestTransport._BaseSearch._get_request_body_json(transcoded_request) + + # Jsonify the query params + query_params = _BaseReportServiceRestTransport._BaseSearch._get_query_params_json(transcoded_request) + + # Send the request + response = ReportServiceRestTransport._Search._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = reports.SearchResponse() + pb_resp = reports.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[ + [reports.SearchRequest], + reports.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 kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ReportServiceRestTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest_base.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest_base.py new file mode 100644 index 000000000000..b7f01e752a42 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest_base.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 json # type: ignore +from google.api_core import path_template +from google.api_core import gapic_v1 + +from google.protobuf import json_format +from .base import ReportServiceTransport, DEFAULT_CLIENT_INFO + +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + + +from google.shopping.merchant_reports_v1beta.types import reports + + +class _BaseReportServiceRestTransport(ReportServiceTransport): + """Base REST backend transport for ReportService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + 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 = 'merchantapi.googleapis.com', + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = 'https', + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'merchantapi.googleapis.com'). + credentials (Optional[Any]): 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. + 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 + 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 + ) + + class _BaseSearch: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/reports/v1beta/{parent=accounts/*}/reports:search', + 'body': '*', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = reports.SearchRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + use_integers_for_enums=True + ) + return body + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseReportServiceRestTransport._BaseSearch._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__=( + '_BaseReportServiceRestTransport', +) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/__init__.py new file mode 100644 index 000000000000..5e965be69091 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/__init__.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .reports import ( + BestSellersBrandView, + BestSellersProductClusterView, + CompetitiveVisibilityBenchmarkView, + CompetitiveVisibilityCompetitorView, + CompetitiveVisibilityTopMerchantView, + MarketingMethod, + NonProductPerformanceView, + PriceCompetitivenessProductView, + PriceInsightsProductView, + ProductPerformanceView, + ProductView, + RelativeDemand, + RelativeDemandChangeType, + ReportGranularity, + ReportRow, + SearchRequest, + SearchResponse, + TrafficSource, +) + +__all__ = ( + 'BestSellersBrandView', + 'BestSellersProductClusterView', + 'CompetitiveVisibilityBenchmarkView', + 'CompetitiveVisibilityCompetitorView', + 'CompetitiveVisibilityTopMerchantView', + 'MarketingMethod', + 'NonProductPerformanceView', + 'PriceCompetitivenessProductView', + 'PriceInsightsProductView', + 'ProductPerformanceView', + 'ProductView', + 'RelativeDemand', + 'RelativeDemandChangeType', + 'ReportGranularity', + 'ReportRow', + 'SearchRequest', + 'SearchResponse', + 'TrafficSource', +) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/reports.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/reports.py new file mode 100644 index 000000000000..49712fcea3ab --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/reports.py @@ -0,0 +1,2521 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.shopping.type.types import types +from google.type import date_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.shopping.merchant.reports.v1beta', + manifest={ + 'SearchRequest', + 'SearchResponse', + 'ReportRow', + 'ProductPerformanceView', + 'ProductView', + 'PriceCompetitivenessProductView', + 'PriceInsightsProductView', + 'BestSellersProductClusterView', + 'BestSellersBrandView', + 'NonProductPerformanceView', + 'CompetitiveVisibilityCompetitorView', + 'CompetitiveVisibilityTopMerchantView', + 'CompetitiveVisibilityBenchmarkView', + 'MarketingMethod', + 'ReportGranularity', + 'RelativeDemand', + 'RelativeDemandChangeType', + 'TrafficSource', + }, +) + + +class SearchRequest(proto.Message): + r"""Request message for the ``ReportService.Search`` method. + + Attributes: + parent (str): + Required. Id of the account making the call. + Must be a standalone account or an MCA + subaccount. Format: accounts/{account} + query (str): + Required. Query that defines a report to be + retrieved. + For details on how to construct your query, see + the Query Language guide. For the full list of + available tables and fields, see the Available + fields. + page_size (int): + Optional. Number of ``ReportRows`` to retrieve in a single + page. Defaults to 1000. Values above 5000 are coerced to + 5000. + page_token (str): + Optional. Token of the page to retrieve. If not specified, + the first page of results is returned. In order to request + the next page of results, the value obtained from + ``next_page_token`` in the previous response should be used. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + query: str = proto.Field( + proto.STRING, + number=2, + ) + page_size: int = proto.Field( + proto.INT32, + number=3, + ) + page_token: str = proto.Field( + proto.STRING, + number=4, + ) + + +class SearchResponse(proto.Message): + r"""Response message for the ``ReportService.Search`` method. + + Attributes: + results (MutableSequence[google.shopping.merchant_reports_v1beta.types.ReportRow]): + Rows that matched the search query. + next_page_token (str): + Token which can be sent as ``page_token`` to retrieve the + next page. If omitted, there are no subsequent pages. + """ + + @property + def raw_page(self): + return self + + results: MutableSequence['ReportRow'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ReportRow', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ReportRow(proto.Message): + r"""Result row returned from the search query. + + Only the message corresponding to the queried table is populated + in the response. Within the populated message, only the fields + requested explicitly in the query are populated. + + Attributes: + product_performance_view (google.shopping.merchant_reports_v1beta.types.ProductPerformanceView): + Fields available for query in ``product_performance_view`` + table. + non_product_performance_view (google.shopping.merchant_reports_v1beta.types.NonProductPerformanceView): + Fields available for query in + ``non_product_performance_view`` table. + product_view (google.shopping.merchant_reports_v1beta.types.ProductView): + Fields available for query in ``product_view`` table. + price_competitiveness_product_view (google.shopping.merchant_reports_v1beta.types.PriceCompetitivenessProductView): + Fields available for query in + ``price_competitiveness_product_view`` table. + price_insights_product_view (google.shopping.merchant_reports_v1beta.types.PriceInsightsProductView): + Fields available for query in + ``price_insights_product_view`` table. + best_sellers_product_cluster_view (google.shopping.merchant_reports_v1beta.types.BestSellersProductClusterView): + Fields available for query in + ``best_sellers_product_cluster_view`` table. + best_sellers_brand_view (google.shopping.merchant_reports_v1beta.types.BestSellersBrandView): + Fields available for query in ``best_sellers_brand_view`` + table. + competitive_visibility_competitor_view (google.shopping.merchant_reports_v1beta.types.CompetitiveVisibilityCompetitorView): + Fields available for query in + ``competitive_visibility_competitor_view`` table. + competitive_visibility_top_merchant_view (google.shopping.merchant_reports_v1beta.types.CompetitiveVisibilityTopMerchantView): + Fields available for query in + ``competitive_visibility_top_merchant_view`` table. + competitive_visibility_benchmark_view (google.shopping.merchant_reports_v1beta.types.CompetitiveVisibilityBenchmarkView): + Fields available for query in + ``competitive_visibility_benchmark_view`` table. + """ + + product_performance_view: 'ProductPerformanceView' = proto.Field( + proto.MESSAGE, + number=1, + message='ProductPerformanceView', + ) + non_product_performance_view: 'NonProductPerformanceView' = proto.Field( + proto.MESSAGE, + number=7, + message='NonProductPerformanceView', + ) + product_view: 'ProductView' = proto.Field( + proto.MESSAGE, + number=2, + message='ProductView', + ) + price_competitiveness_product_view: 'PriceCompetitivenessProductView' = proto.Field( + proto.MESSAGE, + number=3, + message='PriceCompetitivenessProductView', + ) + price_insights_product_view: 'PriceInsightsProductView' = proto.Field( + proto.MESSAGE, + number=4, + message='PriceInsightsProductView', + ) + best_sellers_product_cluster_view: 'BestSellersProductClusterView' = proto.Field( + proto.MESSAGE, + number=5, + message='BestSellersProductClusterView', + ) + best_sellers_brand_view: 'BestSellersBrandView' = proto.Field( + proto.MESSAGE, + number=6, + message='BestSellersBrandView', + ) + competitive_visibility_competitor_view: 'CompetitiveVisibilityCompetitorView' = proto.Field( + proto.MESSAGE, + number=8, + message='CompetitiveVisibilityCompetitorView', + ) + competitive_visibility_top_merchant_view: 'CompetitiveVisibilityTopMerchantView' = proto.Field( + proto.MESSAGE, + number=9, + message='CompetitiveVisibilityTopMerchantView', + ) + competitive_visibility_benchmark_view: 'CompetitiveVisibilityBenchmarkView' = proto.Field( + proto.MESSAGE, + number=10, + message='CompetitiveVisibilityBenchmarkView', + ) + + +class ProductPerformanceView(proto.Message): + r"""Fields available for query in ``product_performance_view`` table. + + Product performance data for your account, including performance + metrics (for example, ``clicks``) and dimensions according to which + performance metrics are segmented (for example, ``offer_id``). + Values of product dimensions, such as ``offer_id``, reflect the + state of a product at the time of the impression. + + Segment fields cannot be selected in queries without also selecting + at least one metric field. + + Values are only set for fields requested explicitly in the request's + search query. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + marketing_method (google.shopping.merchant_reports_v1beta.types.MarketingMethod.MarketingMethodEnum): + Marketing method to which metrics apply. + Segment. + + This field is a member of `oneof`_ ``_marketing_method``. + date (google.type.date_pb2.Date): + Date in the merchant timezone to which metrics apply. + Segment. + + Condition on ``date`` is required in the ``WHERE`` clause. + week (google.type.date_pb2.Date): + First day of the week (Monday) of the metrics + date in the merchant timezone. Segment. + customer_country_code (str): + Code of the country where the customer is + located at the time of the event. Represented in + the ISO 3166 format. Segment. + + If the customer country cannot be determined, a + special 'ZZ' code is returned. + + This field is a member of `oneof`_ ``_customer_country_code``. + offer_id (str): + Merchant-provided id of the product. Segment. + + This field is a member of `oneof`_ ``_offer_id``. + title (str): + Title of the product. Segment. + + This field is a member of `oneof`_ ``_title``. + brand (str): + Brand of the product. Segment. + + This field is a member of `oneof`_ ``_brand``. + category_l1 (str): + `Product category (1st + level) `__ + in Google's product taxonomy. Segment. + + This field is a member of `oneof`_ ``_category_l1``. + category_l2 (str): + `Product category (2nd + level) `__ + in Google's product taxonomy. Segment. + + This field is a member of `oneof`_ ``_category_l2``. + category_l3 (str): + `Product category (3rd + level) `__ + in Google's product taxonomy. Segment. + + This field is a member of `oneof`_ ``_category_l3``. + category_l4 (str): + `Product category (4th + level) `__ + in Google's product taxonomy. Segment. + + This field is a member of `oneof`_ ``_category_l4``. + category_l5 (str): + `Product category (5th + level) `__ + in Google's product taxonomy. Segment. + + This field is a member of `oneof`_ ``_category_l5``. + product_type_l1 (str): + `Product type (1st + level) `__ + in merchant's own product taxonomy. Segment. + + This field is a member of `oneof`_ ``_product_type_l1``. + product_type_l2 (str): + `Product type (2nd + level) `__ + in merchant's own product taxonomy. Segment. + + This field is a member of `oneof`_ ``_product_type_l2``. + product_type_l3 (str): + `Product type (3rd + level) `__ + in merchant's own product taxonomy. Segment. + + This field is a member of `oneof`_ ``_product_type_l3``. + product_type_l4 (str): + `Product type (4th + level) `__ + in merchant's own product taxonomy. Segment. + + This field is a member of `oneof`_ ``_product_type_l4``. + product_type_l5 (str): + `Product type (5th + level) `__ + in merchant's own product taxonomy. Segment. + + This field is a member of `oneof`_ ``_product_type_l5``. + custom_label0 (str): + Custom label 0 for custom grouping of + products. Segment. + + This field is a member of `oneof`_ ``_custom_label0``. + custom_label1 (str): + Custom label 1 for custom grouping of + products. Segment. + + This field is a member of `oneof`_ ``_custom_label1``. + custom_label2 (str): + Custom label 2 for custom grouping of + products. Segment. + + This field is a member of `oneof`_ ``_custom_label2``. + custom_label3 (str): + Custom label 3 for custom grouping of + products. Segment. + + This field is a member of `oneof`_ ``_custom_label3``. + custom_label4 (str): + Custom label 4 for custom grouping of + products. Segment. + + This field is a member of `oneof`_ ``_custom_label4``. + clicks (int): + Number of clicks. Metric. + + This field is a member of `oneof`_ ``_clicks``. + impressions (int): + Number of times merchant's products are + shown. Metric. + + This field is a member of `oneof`_ ``_impressions``. + click_through_rate (float): + Click-through rate - the number of clicks + merchant's products receive (clicks) divided by + the number of times the products are shown + (impressions). Metric. + + This field is a member of `oneof`_ ``_click_through_rate``. + conversions (float): + Number of conversions attributed to the product, reported on + the conversion date. Depending on the attribution model, a + conversion might be distributed across multiple clicks, + where each click gets its own credit assigned. This metric + is a sum of all such credits. Metric. + + Available only for the ``FREE`` traffic source. + + This field is a member of `oneof`_ ``_conversions``. + conversion_value (google.shopping.type.types.Price): + Value of conversions attributed to the product, reported on + the conversion date. Metric. + + Available only for the ``FREE`` traffic source. + conversion_rate (float): + Number of conversions divided by the number of clicks, + reported on the impression date. Metric. + + Available only for the ``FREE`` traffic source. + + This field is a member of `oneof`_ ``_conversion_rate``. + """ + + marketing_method: 'MarketingMethod.MarketingMethodEnum' = proto.Field( + proto.ENUM, + number=1, + optional=True, + enum='MarketingMethod.MarketingMethodEnum', + ) + date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=2, + message=date_pb2.Date, + ) + week: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=3, + message=date_pb2.Date, + ) + customer_country_code: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + offer_id: str = proto.Field( + proto.STRING, + number=5, + optional=True, + ) + title: str = proto.Field( + proto.STRING, + number=6, + optional=True, + ) + brand: str = proto.Field( + proto.STRING, + number=7, + optional=True, + ) + category_l1: str = proto.Field( + proto.STRING, + number=8, + optional=True, + ) + category_l2: str = proto.Field( + proto.STRING, + number=9, + optional=True, + ) + category_l3: str = proto.Field( + proto.STRING, + number=10, + optional=True, + ) + category_l4: str = proto.Field( + proto.STRING, + number=11, + optional=True, + ) + category_l5: str = proto.Field( + proto.STRING, + number=12, + optional=True, + ) + product_type_l1: str = proto.Field( + proto.STRING, + number=13, + optional=True, + ) + product_type_l2: str = proto.Field( + proto.STRING, + number=14, + optional=True, + ) + product_type_l3: str = proto.Field( + proto.STRING, + number=15, + optional=True, + ) + product_type_l4: str = proto.Field( + proto.STRING, + number=16, + optional=True, + ) + product_type_l5: str = proto.Field( + proto.STRING, + number=17, + optional=True, + ) + custom_label0: str = proto.Field( + proto.STRING, + number=18, + optional=True, + ) + custom_label1: str = proto.Field( + proto.STRING, + number=19, + optional=True, + ) + custom_label2: str = proto.Field( + proto.STRING, + number=20, + optional=True, + ) + custom_label3: str = proto.Field( + proto.STRING, + number=21, + optional=True, + ) + custom_label4: str = proto.Field( + proto.STRING, + number=22, + optional=True, + ) + clicks: int = proto.Field( + proto.INT64, + number=23, + optional=True, + ) + impressions: int = proto.Field( + proto.INT64, + number=24, + optional=True, + ) + click_through_rate: float = proto.Field( + proto.DOUBLE, + number=25, + optional=True, + ) + conversions: float = proto.Field( + proto.DOUBLE, + number=26, + optional=True, + ) + conversion_value: types.Price = proto.Field( + proto.MESSAGE, + number=27, + message=types.Price, + ) + conversion_rate: float = proto.Field( + proto.DOUBLE, + number=28, + optional=True, + ) + + +class ProductView(proto.Message): + r"""Fields available for query in ``product_view`` table. + + Products in the current inventory. Products in this table are the + same as in Products sub-API but not all product attributes from + Products sub-API are available for query in this table. In contrast + to Products sub-API, this table allows to filter the returned list + of products by product attributes. To retrieve a single product by + ``id`` or list all products, Products sub-API should be used. + + Values are only set for fields requested explicitly in the request's + search query. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + id (str): + REST ID of the product, in the form of + ``channel~languageCode~feedLabel~offerId``. Merchant API + methods that operate on products take this as their ``name`` + parameter. + + Required in the ``SELECT`` clause. + + This field is a member of `oneof`_ ``_id``. + channel (google.shopping.type.types.Channel.ChannelEnum): + Channel of the product. Can be ``ONLINE`` or ``LOCAL``. + + This field is a member of `oneof`_ ``_channel``. + language_code (str): + Language code of the product in BCP 47 + format. + + This field is a member of `oneof`_ ``_language_code``. + feed_label (str): + Feed label of the product. + + This field is a member of `oneof`_ ``_feed_label``. + offer_id (str): + Merchant-provided id of the product. + + This field is a member of `oneof`_ ``_offer_id``. + title (str): + Title of the product. + + This field is a member of `oneof`_ ``_title``. + brand (str): + Brand of the product. + + This field is a member of `oneof`_ ``_brand``. + category_l1 (str): + Product category (1st level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l1``. + category_l2 (str): + Product category (2nd level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l2``. + category_l3 (str): + Product category (3rd level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l3``. + category_l4 (str): + Product category (4th level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l4``. + category_l5 (str): + Product category (5th level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l5``. + product_type_l1 (str): + Product type (1st level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l1``. + product_type_l2 (str): + Product type (2nd level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l2``. + product_type_l3 (str): + Product type (3rd level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l3``. + product_type_l4 (str): + Product type (4th level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l4``. + product_type_l5 (str): + Product type (5th level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l5``. + price (google.shopping.type.types.Price): + Product price. Absent if the information + about the price of the product is not available. + condition (str): + `Condition `__ + of the product. + + This field is a member of `oneof`_ ``_condition``. + availability (str): + `Availability `__ + of the product. + + This field is a member of `oneof`_ ``_availability``. + shipping_label (str): + Normalized `shipping + label `__ + specified in the data source. + + This field is a member of `oneof`_ ``_shipping_label``. + gtin (MutableSequence[str]): + List of Global Trade Item Numbers (GTINs) of + the product. + item_group_id (str): + Item group id provided by the merchant for + grouping variants together. + + This field is a member of `oneof`_ ``_item_group_id``. + thumbnail_link (str): + Link to the processed image of the product, + hosted on the Google infrastructure. + + This field is a member of `oneof`_ ``_thumbnail_link``. + creation_time (google.protobuf.timestamp_pb2.Timestamp): + The time the merchant created the product in + timestamp seconds. + expiration_date (google.type.date_pb2.Date): + Expiration date for the product, specified on + insertion. + aggregated_reporting_context_status (google.shopping.merchant_reports_v1beta.types.ProductView.AggregatedReportingContextStatus): + Aggregated status. + + This field is a member of `oneof`_ ``_aggregated_reporting_context_status``. + item_issues (MutableSequence[google.shopping.merchant_reports_v1beta.types.ProductView.ItemIssue]): + List of item issues for the product. + + **This field cannot be used for sorting the results.** + + **Only selected attributes of this field (for example, + ``item_issues.severity.aggregated_severity``) can be used + for filtering the results.** + click_potential (google.shopping.merchant_reports_v1beta.types.ProductView.ClickPotential): + Estimated performance potential compared to + highest performing products of the merchant. + click_potential_rank (int): + Rank of the product based on its click potential. A product + with ``click_potential_rank`` 1 has the highest click + potential among the merchant's products that fulfill the + search query conditions. + + This field is a member of `oneof`_ ``_click_potential_rank``. + """ + class AggregatedReportingContextStatus(proto.Enum): + r"""Status of the product aggregated for all reporting contexts. + + Here's an example of how the aggregated status is computed: + + Free listings \| Shopping ads \| Status + --------------|--------------|------------------------------ + Approved \| Approved \| ELIGIBLE Approved \| Pending \| ELIGIBLE + Approved \| Disapproved \| ELIGIBLE_LIMITED Pending \| Pending \| + PENDING Disapproved \| Disapproved \| NOT_ELIGIBLE_OR_DISAPPROVED + + Values: + AGGREGATED_REPORTING_CONTEXT_STATUS_UNSPECIFIED (0): + Not specified. + NOT_ELIGIBLE_OR_DISAPPROVED (1): + Product is not eligible or is disapproved for + all reporting contexts. + PENDING (2): + Product's status is pending in all reporting + contexts. + ELIGIBLE_LIMITED (3): + Product is eligible for some (but not all) + reporting contexts. + ELIGIBLE (4): + Product is eligible for all reporting + contexts. + """ + AGGREGATED_REPORTING_CONTEXT_STATUS_UNSPECIFIED = 0 + NOT_ELIGIBLE_OR_DISAPPROVED = 1 + PENDING = 2 + ELIGIBLE_LIMITED = 3 + ELIGIBLE = 4 + + class ClickPotential(proto.Enum): + r"""A product's `click + potential `__ + estimates its performance potential compared to highest performing + products of the merchant. Click potential of a product helps + merchants to prioritize which products to fix and helps them + understand how products are performing against their potential. + + Values: + CLICK_POTENTIAL_UNSPECIFIED (0): + Unknown predicted clicks impact. + LOW (1): + Potential to receive a low number of clicks + compared to the highest performing products of + the merchant. + MEDIUM (2): + Potential to receive a moderate number of + clicks compared to the highest performing + products of the merchant. + HIGH (3): + Potential to receive a similar number of + clicks as the highest performing products of the + merchant. + """ + CLICK_POTENTIAL_UNSPECIFIED = 0 + LOW = 1 + MEDIUM = 2 + HIGH = 3 + + class ItemIssue(proto.Message): + r"""Item issue associated with the product. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + type_ (google.shopping.merchant_reports_v1beta.types.ProductView.ItemIssue.ItemIssueType): + Item issue type. + severity (google.shopping.merchant_reports_v1beta.types.ProductView.ItemIssue.ItemIssueSeverity): + Item issue severity. + resolution (google.shopping.merchant_reports_v1beta.types.ProductView.ItemIssue.ItemIssueResolution): + Item issue resolution. + + This field is a member of `oneof`_ ``_resolution``. + """ + class ItemIssueResolution(proto.Enum): + r"""How to resolve the issue. + + Values: + ITEM_ISSUE_RESOLUTION_UNSPECIFIED (0): + Not specified. + MERCHANT_ACTION (1): + The merchant has to fix the issue. + PENDING_PROCESSING (2): + The issue will be resolved automatically (for + example, image crawl) or through a Google + review. No merchant action is required now. + Resolution might lead to another issue (for + example, if crawl fails). + """ + ITEM_ISSUE_RESOLUTION_UNSPECIFIED = 0 + MERCHANT_ACTION = 1 + PENDING_PROCESSING = 2 + + class ItemIssueType(proto.Message): + r"""Issue type. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + code (str): + Error code of the issue, equivalent to the ``code`` of + `Product + issues `__. + + This field is a member of `oneof`_ ``_code``. + canonical_attribute (str): + Canonical attribute name for + attribute-specific issues. + + This field is a member of `oneof`_ ``_canonical_attribute``. + """ + + code: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + canonical_attribute: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + + class ItemIssueSeverity(proto.Message): + r"""How the issue affects the serving of the product. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + severity_per_reporting_context (MutableSequence[google.shopping.merchant_reports_v1beta.types.ProductView.ItemIssue.ItemIssueSeverity.IssueSeverityPerReportingContext]): + Issue severity per reporting context. + aggregated_severity (google.shopping.merchant_reports_v1beta.types.ProductView.ItemIssue.ItemIssueSeverity.AggregatedIssueSeverity): + Aggregated severity of the issue for all reporting contexts + it affects. + + **This field can be used for filtering the results.** + + This field is a member of `oneof`_ ``_aggregated_severity``. + """ + class AggregatedIssueSeverity(proto.Enum): + r"""Issue severity aggregated for all reporting contexts. + + Values: + AGGREGATED_ISSUE_SEVERITY_UNSPECIFIED (0): + Not specified. + DISAPPROVED (1): + Issue disapproves the product in at least one + reporting context. + DEMOTED (2): + Issue demotes the product in all reporting + contexts it affects. + PENDING (3): + Issue resolution is ``PENDING_PROCESSING``. + """ + AGGREGATED_ISSUE_SEVERITY_UNSPECIFIED = 0 + DISAPPROVED = 1 + DEMOTED = 2 + PENDING = 3 + + class IssueSeverityPerReportingContext(proto.Message): + r"""Issue severity per reporting context. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + reporting_context (google.shopping.type.types.ReportingContext.ReportingContextEnum): + Reporting context the issue applies to. + + This field is a member of `oneof`_ ``_reporting_context``. + disapproved_countries (MutableSequence[str]): + List of disapproved countries in the + reporting context, represented in ISO 3166 + format. + demoted_countries (MutableSequence[str]): + List of demoted countries in the reporting + context, represented in ISO 3166 format. + """ + + reporting_context: types.ReportingContext.ReportingContextEnum = proto.Field( + proto.ENUM, + number=1, + optional=True, + enum=types.ReportingContext.ReportingContextEnum, + ) + disapproved_countries: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + demoted_countries: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + severity_per_reporting_context: MutableSequence['ProductView.ItemIssue.ItemIssueSeverity.IssueSeverityPerReportingContext'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='ProductView.ItemIssue.ItemIssueSeverity.IssueSeverityPerReportingContext', + ) + aggregated_severity: 'ProductView.ItemIssue.ItemIssueSeverity.AggregatedIssueSeverity' = proto.Field( + proto.ENUM, + number=2, + optional=True, + enum='ProductView.ItemIssue.ItemIssueSeverity.AggregatedIssueSeverity', + ) + + type_: 'ProductView.ItemIssue.ItemIssueType' = proto.Field( + proto.MESSAGE, + number=1, + message='ProductView.ItemIssue.ItemIssueType', + ) + severity: 'ProductView.ItemIssue.ItemIssueSeverity' = proto.Field( + proto.MESSAGE, + number=2, + message='ProductView.ItemIssue.ItemIssueSeverity', + ) + resolution: 'ProductView.ItemIssue.ItemIssueResolution' = proto.Field( + proto.ENUM, + number=3, + optional=True, + enum='ProductView.ItemIssue.ItemIssueResolution', + ) + + id: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + channel: types.Channel.ChannelEnum = proto.Field( + proto.ENUM, + number=28, + optional=True, + enum=types.Channel.ChannelEnum, + ) + language_code: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + feed_label: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + offer_id: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + title: str = proto.Field( + proto.STRING, + number=5, + optional=True, + ) + brand: str = proto.Field( + proto.STRING, + number=6, + optional=True, + ) + category_l1: str = proto.Field( + proto.STRING, + number=7, + optional=True, + ) + category_l2: str = proto.Field( + proto.STRING, + number=8, + optional=True, + ) + category_l3: str = proto.Field( + proto.STRING, + number=9, + optional=True, + ) + category_l4: str = proto.Field( + proto.STRING, + number=10, + optional=True, + ) + category_l5: str = proto.Field( + proto.STRING, + number=11, + optional=True, + ) + product_type_l1: str = proto.Field( + proto.STRING, + number=12, + optional=True, + ) + product_type_l2: str = proto.Field( + proto.STRING, + number=13, + optional=True, + ) + product_type_l3: str = proto.Field( + proto.STRING, + number=14, + optional=True, + ) + product_type_l4: str = proto.Field( + proto.STRING, + number=15, + optional=True, + ) + product_type_l5: str = proto.Field( + proto.STRING, + number=16, + optional=True, + ) + price: types.Price = proto.Field( + proto.MESSAGE, + number=17, + message=types.Price, + ) + condition: str = proto.Field( + proto.STRING, + number=18, + optional=True, + ) + availability: str = proto.Field( + proto.STRING, + number=19, + optional=True, + ) + shipping_label: str = proto.Field( + proto.STRING, + number=20, + optional=True, + ) + gtin: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=21, + ) + item_group_id: str = proto.Field( + proto.STRING, + number=22, + optional=True, + ) + thumbnail_link: str = proto.Field( + proto.STRING, + number=23, + optional=True, + ) + creation_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=24, + message=timestamp_pb2.Timestamp, + ) + expiration_date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=25, + message=date_pb2.Date, + ) + aggregated_reporting_context_status: AggregatedReportingContextStatus = proto.Field( + proto.ENUM, + number=26, + optional=True, + enum=AggregatedReportingContextStatus, + ) + item_issues: MutableSequence[ItemIssue] = proto.RepeatedField( + proto.MESSAGE, + number=27, + message=ItemIssue, + ) + click_potential: ClickPotential = proto.Field( + proto.ENUM, + number=29, + enum=ClickPotential, + ) + click_potential_rank: int = proto.Field( + proto.INT64, + number=30, + optional=True, + ) + + +class PriceCompetitivenessProductView(proto.Message): + r"""Fields available for query in ``price_competitiveness_product_view`` + table. + + `Price + competitiveness `__ + report. + + Values are only set for fields requested explicitly in the request's + search query. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + report_country_code (str): + Country of the price benchmark. Represented in the ISO 3166 + format. + + Required in the ``SELECT`` clause. + + This field is a member of `oneof`_ ``_report_country_code``. + id (str): + REST ID of the product, in the form of + ``channel~languageCode~feedLabel~offerId``. Can be used to + join data with the ``product_view`` table. + + Required in the ``SELECT`` clause. + + This field is a member of `oneof`_ ``_id``. + offer_id (str): + Merchant-provided id of the product. + + This field is a member of `oneof`_ ``_offer_id``. + title (str): + Title of the product. + + This field is a member of `oneof`_ ``_title``. + brand (str): + Brand of the product. + + This field is a member of `oneof`_ ``_brand``. + category_l1 (str): + Product category (1st level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l1``. + category_l2 (str): + Product category (2nd level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l2``. + category_l3 (str): + Product category (3rd level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l3``. + category_l4 (str): + Product category (4th level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l4``. + category_l5 (str): + Product category (5th level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l5``. + product_type_l1 (str): + Product type (1st level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l1``. + product_type_l2 (str): + Product type (2nd level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l2``. + product_type_l3 (str): + Product type (3rd level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l3``. + product_type_l4 (str): + Product type (4th level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l4``. + product_type_l5 (str): + Product type (5th level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l5``. + price (google.shopping.type.types.Price): + Current price of the product. + benchmark_price (google.shopping.type.types.Price): + Latest available price benchmark for the + product's catalog in the benchmark country. + """ + + report_country_code: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + id: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + offer_id: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + title: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + brand: str = proto.Field( + proto.STRING, + number=5, + optional=True, + ) + category_l1: str = proto.Field( + proto.STRING, + number=6, + optional=True, + ) + category_l2: str = proto.Field( + proto.STRING, + number=7, + optional=True, + ) + category_l3: str = proto.Field( + proto.STRING, + number=8, + optional=True, + ) + category_l4: str = proto.Field( + proto.STRING, + number=9, + optional=True, + ) + category_l5: str = proto.Field( + proto.STRING, + number=10, + optional=True, + ) + product_type_l1: str = proto.Field( + proto.STRING, + number=11, + optional=True, + ) + product_type_l2: str = proto.Field( + proto.STRING, + number=12, + optional=True, + ) + product_type_l3: str = proto.Field( + proto.STRING, + number=13, + optional=True, + ) + product_type_l4: str = proto.Field( + proto.STRING, + number=14, + optional=True, + ) + product_type_l5: str = proto.Field( + proto.STRING, + number=15, + optional=True, + ) + price: types.Price = proto.Field( + proto.MESSAGE, + number=16, + message=types.Price, + ) + benchmark_price: types.Price = proto.Field( + proto.MESSAGE, + number=17, + message=types.Price, + ) + + +class PriceInsightsProductView(proto.Message): + r"""Fields available for query in ``price_insights_product_view`` table. + + `Price + insights `__ + report. + + Values are only set for fields requested explicitly in the request's + search query. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + id (str): + REST ID of the product, in the form of + ``channel~languageCode~feedLabel~offerId``. Can be used to + join data with the ``product_view`` table. + + Required in the ``SELECT`` clause. + + This field is a member of `oneof`_ ``_id``. + offer_id (str): + Merchant-provided id of the product. + + This field is a member of `oneof`_ ``_offer_id``. + title (str): + Title of the product. + + This field is a member of `oneof`_ ``_title``. + brand (str): + Brand of the product. + + This field is a member of `oneof`_ ``_brand``. + category_l1 (str): + Product category (1st level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l1``. + category_l2 (str): + Product category (2nd level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l2``. + category_l3 (str): + Product category (3rd level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l3``. + category_l4 (str): + Product category (4th level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l4``. + category_l5 (str): + Product category (5th level) in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l5``. + product_type_l1 (str): + Product type (1st level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l1``. + product_type_l2 (str): + Product type (2nd level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l2``. + product_type_l3 (str): + Product type (3rd level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l3``. + product_type_l4 (str): + Product type (4th level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l4``. + product_type_l5 (str): + Product type (5th level) in merchant's own `product + taxonomy `__. + + This field is a member of `oneof`_ ``_product_type_l5``. + price (google.shopping.type.types.Price): + Current price of the product. + suggested_price (google.shopping.type.types.Price): + Latest suggested price for the product. + predicted_impressions_change_fraction (float): + Predicted change in impressions as a fraction + after introducing the suggested price compared + to current active price. For example, 0.05 is a + 5% predicted increase in impressions. + + This field is a member of `oneof`_ ``_predicted_impressions_change_fraction``. + predicted_clicks_change_fraction (float): + Predicted change in clicks as a fraction + after introducing the suggested price compared + to current active price. For example, 0.05 is a + 5% predicted increase in clicks. + + This field is a member of `oneof`_ ``_predicted_clicks_change_fraction``. + predicted_conversions_change_fraction (float): + Predicted change in conversions as a fraction + after introducing the suggested price compared + to current active price. For example, 0.05 is a + 5% predicted increase in conversions). + + This field is a member of `oneof`_ ``_predicted_conversions_change_fraction``. + effectiveness (google.shopping.merchant_reports_v1beta.types.PriceInsightsProductView.Effectiveness): + The predicted effectiveness of applying the + price suggestion, bucketed. + """ + class Effectiveness(proto.Enum): + r"""Predicted effectiveness bucket. + + Effectiveness indicates which products would benefit most from price + changes. This rating takes into consideration the performance boost + predicted by adjusting the sale price and the difference between + your current price and the suggested price. Price suggestions with + ``HIGH`` effectiveness are predicted to drive the largest increase + in performance. + + Values: + EFFECTIVENESS_UNSPECIFIED (0): + Effectiveness is unknown. + LOW (1): + Effectiveness is low. + MEDIUM (2): + Effectiveness is medium. + HIGH (3): + Effectiveness is high. + """ + EFFECTIVENESS_UNSPECIFIED = 0 + LOW = 1 + MEDIUM = 2 + HIGH = 3 + + id: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + offer_id: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + title: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + brand: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + category_l1: str = proto.Field( + proto.STRING, + number=5, + optional=True, + ) + category_l2: str = proto.Field( + proto.STRING, + number=6, + optional=True, + ) + category_l3: str = proto.Field( + proto.STRING, + number=7, + optional=True, + ) + category_l4: str = proto.Field( + proto.STRING, + number=8, + optional=True, + ) + category_l5: str = proto.Field( + proto.STRING, + number=9, + optional=True, + ) + product_type_l1: str = proto.Field( + proto.STRING, + number=10, + optional=True, + ) + product_type_l2: str = proto.Field( + proto.STRING, + number=11, + optional=True, + ) + product_type_l3: str = proto.Field( + proto.STRING, + number=12, + optional=True, + ) + product_type_l4: str = proto.Field( + proto.STRING, + number=13, + optional=True, + ) + product_type_l5: str = proto.Field( + proto.STRING, + number=14, + optional=True, + ) + price: types.Price = proto.Field( + proto.MESSAGE, + number=15, + message=types.Price, + ) + suggested_price: types.Price = proto.Field( + proto.MESSAGE, + number=16, + message=types.Price, + ) + predicted_impressions_change_fraction: float = proto.Field( + proto.DOUBLE, + number=17, + optional=True, + ) + predicted_clicks_change_fraction: float = proto.Field( + proto.DOUBLE, + number=18, + optional=True, + ) + predicted_conversions_change_fraction: float = proto.Field( + proto.DOUBLE, + number=19, + optional=True, + ) + effectiveness: Effectiveness = proto.Field( + proto.ENUM, + number=22, + enum=Effectiveness, + ) + + +class BestSellersProductClusterView(proto.Message): + r"""Fields available for query in ``best_sellers_product_cluster_view`` + table. + + `Best + sellers `__ + report with top product clusters. A product cluster is a grouping + for different offers and variants that represent the same product, + for example, Google Pixel 7. + + Values are only set for fields requested explicitly in the request's + search query. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + report_date (google.type.date_pb2.Date): + Report date. The value of this field can only be one of the + following: + + - The first day of the week (Monday) for weekly reports, + - The first day of the month for monthly reports. + + Required in the ``SELECT`` clause. If a ``WHERE`` condition + on ``report_date`` is not specified in the query, the latest + available weekly or monthly report is returned. + report_granularity (google.shopping.merchant_reports_v1beta.types.ReportGranularity.ReportGranularityEnum): + Granularity of the report. The ranking can be done over a + week or a month timeframe. + + Required in the ``SELECT`` clause. Condition on + ``report_granularity`` is required in the ``WHERE`` clause. + + This field is a member of `oneof`_ ``_report_granularity``. + report_country_code (str): + Country where the ranking is calculated. Represented in the + ISO 3166 format. + + Required in the ``SELECT`` clause. Condition on + ``report_country_code`` is required in the ``WHERE`` clause. + + This field is a member of `oneof`_ ``_report_country_code``. + report_category_id (int): + Google product category ID to calculate the ranking for, + represented in `Google's product + taxonomy `__. + + Required in the ``SELECT`` clause. If a ``WHERE`` condition + on ``report_category_id`` is not specified in the query, + rankings for all top-level categories are returned. + + This field is a member of `oneof`_ ``_report_category_id``. + title (str): + Title of the product cluster. + + This field is a member of `oneof`_ ``_title``. + brand (str): + Brand of the product cluster. + + This field is a member of `oneof`_ ``_brand``. + category_l1 (str): + Product category (1st level) of the product cluster, + represented in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l1``. + category_l2 (str): + Product category (2nd level) of the product cluster, + represented in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l2``. + category_l3 (str): + Product category (3rd level) of the product cluster, + represented in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l3``. + category_l4 (str): + Product category (4th level) of the product cluster, + represented in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l4``. + category_l5 (str): + Product category (5th level) of the product cluster, + represented in `Google's product + taxonomy `__. + + This field is a member of `oneof`_ ``_category_l5``. + variant_gtins (MutableSequence[str]): + GTINs of example variants of the product + cluster. + inventory_status (google.shopping.merchant_reports_v1beta.types.BestSellersProductClusterView.InventoryStatus): + Whether the product cluster is ``IN_STOCK`` in your product + data source in at least one of the countries, + ``OUT_OF_STOCK`` in your product data source in all + countries, or ``NOT_IN_INVENTORY`` at all. + + The field doesn't take the Best sellers report country + filter into account. + + This field is a member of `oneof`_ ``_inventory_status``. + brand_inventory_status (google.shopping.merchant_reports_v1beta.types.BestSellersProductClusterView.InventoryStatus): + Whether there is at least one product of the brand currently + ``IN_STOCK`` in your product data source in at least one of + the countries, all products are ``OUT_OF_STOCK`` in your + product data source in all countries, or + ``NOT_IN_INVENTORY``. + + The field doesn't take the Best sellers report country + filter into account. + + This field is a member of `oneof`_ ``_brand_inventory_status``. + rank (int): + Popularity of the product cluster on Ads and + organic surfaces, in the selected category and + country, based on the estimated number of units + sold. + + This field is a member of `oneof`_ ``_rank``. + previous_rank (int): + Popularity rank in the previous week or + month. + + This field is a member of `oneof`_ ``_previous_rank``. + relative_demand (google.shopping.merchant_reports_v1beta.types.RelativeDemand.RelativeDemandEnum): + Estimated demand in relation to the product + cluster with the highest popularity rank in the + same category and country. + + This field is a member of `oneof`_ ``_relative_demand``. + previous_relative_demand (google.shopping.merchant_reports_v1beta.types.RelativeDemand.RelativeDemandEnum): + Estimated demand in relation to the product + cluster with the highest popularity rank in the + same category and country in the previous week + or month. + + This field is a member of `oneof`_ ``_previous_relative_demand``. + relative_demand_change (google.shopping.merchant_reports_v1beta.types.RelativeDemandChangeType.RelativeDemandChangeTypeEnum): + Change in the estimated demand. Whether it + rose, sank or remained flat. + + This field is a member of `oneof`_ ``_relative_demand_change``. + """ + class InventoryStatus(proto.Enum): + r"""Status of the product cluster or brand in your inventory. + + Values: + INVENTORY_STATUS_UNSPECIFIED (0): + Not specified. + IN_STOCK (1): + You have a product for this product cluster + or brand in stock. + OUT_OF_STOCK (2): + You have a product for this product cluster + or brand in inventory but it is currently out of + stock. + NOT_IN_INVENTORY (3): + You do not have a product for this product + cluster or brand in inventory. + """ + INVENTORY_STATUS_UNSPECIFIED = 0 + IN_STOCK = 1 + OUT_OF_STOCK = 2 + NOT_IN_INVENTORY = 3 + + report_date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=1, + message=date_pb2.Date, + ) + report_granularity: 'ReportGranularity.ReportGranularityEnum' = proto.Field( + proto.ENUM, + number=2, + optional=True, + enum='ReportGranularity.ReportGranularityEnum', + ) + report_country_code: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + report_category_id: int = proto.Field( + proto.INT64, + number=4, + optional=True, + ) + title: str = proto.Field( + proto.STRING, + number=6, + optional=True, + ) + brand: str = proto.Field( + proto.STRING, + number=7, + optional=True, + ) + category_l1: str = proto.Field( + proto.STRING, + number=8, + optional=True, + ) + category_l2: str = proto.Field( + proto.STRING, + number=9, + optional=True, + ) + category_l3: str = proto.Field( + proto.STRING, + number=10, + optional=True, + ) + category_l4: str = proto.Field( + proto.STRING, + number=11, + optional=True, + ) + category_l5: str = proto.Field( + proto.STRING, + number=12, + optional=True, + ) + variant_gtins: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=13, + ) + inventory_status: InventoryStatus = proto.Field( + proto.ENUM, + number=14, + optional=True, + enum=InventoryStatus, + ) + brand_inventory_status: InventoryStatus = proto.Field( + proto.ENUM, + number=15, + optional=True, + enum=InventoryStatus, + ) + rank: int = proto.Field( + proto.INT64, + number=16, + optional=True, + ) + previous_rank: int = proto.Field( + proto.INT64, + number=17, + optional=True, + ) + relative_demand: 'RelativeDemand.RelativeDemandEnum' = proto.Field( + proto.ENUM, + number=18, + optional=True, + enum='RelativeDemand.RelativeDemandEnum', + ) + previous_relative_demand: 'RelativeDemand.RelativeDemandEnum' = proto.Field( + proto.ENUM, + number=19, + optional=True, + enum='RelativeDemand.RelativeDemandEnum', + ) + relative_demand_change: 'RelativeDemandChangeType.RelativeDemandChangeTypeEnum' = proto.Field( + proto.ENUM, + number=20, + optional=True, + enum='RelativeDemandChangeType.RelativeDemandChangeTypeEnum', + ) + + +class BestSellersBrandView(proto.Message): + r"""Fields available for query in ``best_sellers_brand_view`` table. + + `Best + sellers `__ + report with top brands. + + Values are only set for fields requested explicitly in the request's + search query. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + report_date (google.type.date_pb2.Date): + Report date. The value of this field can only be one of the + following: + + - The first day of the week (Monday) for weekly reports, + - The first day of the month for monthly reports. + + Required in the ``SELECT`` clause. If a ``WHERE`` condition + on ``report_date`` is not specified in the query, the latest + available weekly or monthly report is returned. + report_granularity (google.shopping.merchant_reports_v1beta.types.ReportGranularity.ReportGranularityEnum): + Granularity of the report. The ranking can be done over a + week or a month timeframe. + + Required in the ``SELECT`` clause. Condition on + ``report_granularity`` is required in the ``WHERE`` clause. + + This field is a member of `oneof`_ ``_report_granularity``. + report_country_code (str): + Country where the ranking is calculated. Represented in the + ISO 3166 format. + + Required in the ``SELECT`` clause. Condition on + ``report_country_code`` is required in the ``WHERE`` clause. + + This field is a member of `oneof`_ ``_report_country_code``. + report_category_id (int): + Google product category ID to calculate the ranking for, + represented in `Google's product + taxonomy `__. + + Required in the ``SELECT`` clause. If a ``WHERE`` condition + on ``report_category_id`` is not specified in the query, + rankings for all top-level categories are returned. + + This field is a member of `oneof`_ ``_report_category_id``. + brand (str): + Name of the brand. + + This field is a member of `oneof`_ ``_brand``. + rank (int): + Popularity of the brand on Ads and organic + surfaces, in the selected category and country, + based on the estimated number of units sold. + + This field is a member of `oneof`_ ``_rank``. + previous_rank (int): + Popularity rank in the previous week or + month. + + This field is a member of `oneof`_ ``_previous_rank``. + relative_demand (google.shopping.merchant_reports_v1beta.types.RelativeDemand.RelativeDemandEnum): + Estimated demand in relation to the brand + with the highest popularity rank in the same + category and country. + + This field is a member of `oneof`_ ``_relative_demand``. + previous_relative_demand (google.shopping.merchant_reports_v1beta.types.RelativeDemand.RelativeDemandEnum): + Estimated demand in relation to the brand + with the highest popularity rank in the same + category and country in the previous week or + month. + + This field is a member of `oneof`_ ``_previous_relative_demand``. + relative_demand_change (google.shopping.merchant_reports_v1beta.types.RelativeDemandChangeType.RelativeDemandChangeTypeEnum): + Change in the estimated demand. Whether it + rose, sank or remained flat. + + This field is a member of `oneof`_ ``_relative_demand_change``. + """ + + report_date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=1, + message=date_pb2.Date, + ) + report_granularity: 'ReportGranularity.ReportGranularityEnum' = proto.Field( + proto.ENUM, + number=2, + optional=True, + enum='ReportGranularity.ReportGranularityEnum', + ) + report_country_code: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + report_category_id: int = proto.Field( + proto.INT64, + number=4, + optional=True, + ) + brand: str = proto.Field( + proto.STRING, + number=6, + optional=True, + ) + rank: int = proto.Field( + proto.INT64, + number=7, + optional=True, + ) + previous_rank: int = proto.Field( + proto.INT64, + number=8, + optional=True, + ) + relative_demand: 'RelativeDemand.RelativeDemandEnum' = proto.Field( + proto.ENUM, + number=9, + optional=True, + enum='RelativeDemand.RelativeDemandEnum', + ) + previous_relative_demand: 'RelativeDemand.RelativeDemandEnum' = proto.Field( + proto.ENUM, + number=10, + optional=True, + enum='RelativeDemand.RelativeDemandEnum', + ) + relative_demand_change: 'RelativeDemandChangeType.RelativeDemandChangeTypeEnum' = proto.Field( + proto.ENUM, + number=11, + optional=True, + enum='RelativeDemandChangeType.RelativeDemandChangeTypeEnum', + ) + + +class NonProductPerformanceView(proto.Message): + r"""Fields available for query in ``non_product_performance_view`` + table. + + Performance data on images and online store links leading to your + non-product pages. This includes performance metrics (for example, + ``clicks``) and dimensions according to which performance metrics + are segmented (for example, ``date``). + + Segment fields cannot be selected in queries without also selecting + at least one metric field. + + Values are only set for fields requested explicitly in the request's + search query. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + date (google.type.date_pb2.Date): + Date in the merchant timezone to which metrics apply. + Segment. + + Condition on ``date`` is required in the ``WHERE`` clause. + week (google.type.date_pb2.Date): + First day of the week (Monday) of the metrics + date in the merchant timezone. Segment. + clicks (int): + Number of clicks on images and online store + links leading to your non-product pages. Metric. + + This field is a member of `oneof`_ ``_clicks``. + impressions (int): + Number of times images and online store links + leading to your non-product pages were shown. + Metric. + + This field is a member of `oneof`_ ``_impressions``. + click_through_rate (float): + Click-through rate - the number of clicks (``clicks``) + divided by the number of impressions (``impressions``) of + images and online store links leading to your non-product + pages. Metric. + + This field is a member of `oneof`_ ``_click_through_rate``. + """ + + date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=1, + message=date_pb2.Date, + ) + week: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=2, + message=date_pb2.Date, + ) + clicks: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + impressions: int = proto.Field( + proto.INT64, + number=4, + optional=True, + ) + click_through_rate: float = proto.Field( + proto.DOUBLE, + number=5, + optional=True, + ) + + +class CompetitiveVisibilityCompetitorView(proto.Message): + r"""Fields available for query in + ``competitive_visibility_competitor_view`` table. + + `Competitive + visibility `__ + report with businesses with similar visibility. + + Values are only set for fields requested explicitly in the request's + search query. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + date (google.type.date_pb2.Date): + Date of this row. + + A condition on ``date`` is required in the ``WHERE`` clause. + domain (str): + Domain of your competitor or your domain, if + 'is_your_domain' is true. + + Required in the ``SELECT`` clause. Cannot be filtered on in + the 'WHERE' clause. + + This field is a member of `oneof`_ ``_domain``. + is_your_domain (bool): + True if this row contains data for your + domain. + Cannot be filtered on in the 'WHERE' clause. + + This field is a member of `oneof`_ ``_is_your_domain``. + report_country_code (str): + Country where impressions appeared. + + Required in the ``SELECT`` clause. A condition on + ``report_country_code`` is required in the ``WHERE`` clause. + + This field is a member of `oneof`_ ``_report_country_code``. + report_category_id (int): + Google product category ID to calculate the report for, + represented in `Google's product + taxonomy `__. + + Required in the ``SELECT`` clause. A condition on + ``report_category_id`` is required in the ``WHERE`` clause. + + This field is a member of `oneof`_ ``_report_category_id``. + traffic_source (google.shopping.merchant_reports_v1beta.types.TrafficSource.TrafficSourceEnum): + Traffic source of impressions. + + Required in the ``SELECT`` clause. + + This field is a member of `oneof`_ ``_traffic_source``. + rank (int): + Position of the domain in the similar businesses ranking for + the selected keys (``date``, ``report_category_id``, + ``report_country_code``, ``traffic_source``) based on + impressions. 1 is the highest. + + Cannot be filtered on in the 'WHERE' clause. + + This field is a member of `oneof`_ ``_rank``. + ads_organic_ratio (float): + [Ads / organic ratio] + (https://support.google.com/merchants/answer/11366442#zippy=%2Cads-free-ratio) + shows how often the domain receives impressions from + Shopping ads compared to organic traffic. The number is + rounded and bucketed. + + Cannot be filtered on in the 'WHERE' clause. + + This field is a member of `oneof`_ ``_ads_organic_ratio``. + page_overlap_rate (float): + [Page overlap rate] + (https://support.google.com/merchants/answer/11366442#zippy=%2Cpage-overlap-rate) + shows how frequently competing retailers’ offers are shown + together with your offers on the same page. + + Cannot be filtered on in the 'WHERE' clause. + + This field is a member of `oneof`_ ``_page_overlap_rate``. + higher_position_rate (float): + [Higher position rate] + (https://support.google.com/merchants/answer/11366442#zippy=%2Chigher-position-rate) + shows how often a competitor’s offer got placed in a higher + position on the page than your offer. + + Cannot be filtered on in the 'WHERE' clause. + + This field is a member of `oneof`_ ``_higher_position_rate``. + relative_visibility (float): + [Relative visibility] + (https://support.google.com/merchants/answer/11366442#zippy=%2Crelative-visibility) + shows how often your competitors’ offers are shown compared + to your offers. In other words, this is the number of + displayed impressions of a competitor retailer divided by + the number of your displayed impressions during a selected + time range for a selected product category and country. + + Cannot be filtered on in the 'WHERE' clause. + + This field is a member of `oneof`_ ``_relative_visibility``. + """ + + date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=1, + message=date_pb2.Date, + ) + domain: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + is_your_domain: bool = proto.Field( + proto.BOOL, + number=3, + optional=True, + ) + report_country_code: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + report_category_id: int = proto.Field( + proto.INT64, + number=5, + optional=True, + ) + traffic_source: 'TrafficSource.TrafficSourceEnum' = proto.Field( + proto.ENUM, + number=6, + optional=True, + enum='TrafficSource.TrafficSourceEnum', + ) + rank: int = proto.Field( + proto.INT64, + number=7, + optional=True, + ) + ads_organic_ratio: float = proto.Field( + proto.DOUBLE, + number=8, + optional=True, + ) + page_overlap_rate: float = proto.Field( + proto.DOUBLE, + number=9, + optional=True, + ) + higher_position_rate: float = proto.Field( + proto.DOUBLE, + number=10, + optional=True, + ) + relative_visibility: float = proto.Field( + proto.DOUBLE, + number=11, + optional=True, + ) + + +class CompetitiveVisibilityTopMerchantView(proto.Message): + r"""Fields available for query in + ``competitive_visibility_top_merchant_view`` table. + + `Competitive + visibility `__ + report with business with highest visibility. + + Values are only set for fields requested explicitly in the request's + search query. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + date (google.type.date_pb2.Date): + Date of this row. + + Cannot be selected in the ``SELECT`` clause. A condition on + ``date`` is required in the ``WHERE`` clause. + domain (str): + Domain of your competitor or your domain, if + 'is_your_domain' is true. + + Required in the ``SELECT`` clause. Cannot be filtered on in + the 'WHERE' clause. + + This field is a member of `oneof`_ ``_domain``. + is_your_domain (bool): + True if this row contains data for your + domain. + Cannot be filtered on in the 'WHERE' clause. + + This field is a member of `oneof`_ ``_is_your_domain``. + report_country_code (str): + Country where impressions appeared. + + Required in the ``SELECT`` clause. A condition on + ``report_country_code`` is required in the ``WHERE`` clause. + + This field is a member of `oneof`_ ``_report_country_code``. + report_category_id (int): + Google product category ID to calculate the report for, + represented in `Google's product + taxonomy `__. + + Required in the ``SELECT`` clause. A condition on + ``report_category_id`` is required in the ``WHERE`` clause. + + This field is a member of `oneof`_ ``_report_category_id``. + traffic_source (google.shopping.merchant_reports_v1beta.types.TrafficSource.TrafficSourceEnum): + Traffic source of impressions. + + Required in the ``SELECT`` clause. + + This field is a member of `oneof`_ ``_traffic_source``. + rank (int): + Position of the domain in the top merchants ranking for the + selected keys (``date``, ``report_category_id``, + ``report_country_code``, ``traffic_source``) based on + impressions. 1 is the highest. + + Cannot be filtered on in the 'WHERE' clause. + + This field is a member of `oneof`_ ``_rank``. + ads_organic_ratio (float): + [Ads / organic ratio] + (https://support.google.com/merchants/answer/11366442#zippy=%2Cads-free-ratio) + shows how often the domain receives impressions from + Shopping ads compared to organic traffic. The number is + rounded and bucketed. + + Cannot be filtered on in the 'WHERE' clause. + + This field is a member of `oneof`_ ``_ads_organic_ratio``. + page_overlap_rate (float): + [Page overlap rate] + (https://support.google.com/merchants/answer/11366442#zippy=%2Cpage-overlap-rate) + shows how frequently competing retailers’ offers are shown + together with your offers on the same page. + + Cannot be filtered on in the 'WHERE' clause. + + This field is a member of `oneof`_ ``_page_overlap_rate``. + higher_position_rate (float): + [Higher position rate] + (https://support.google.com/merchants/answer/11366442#zippy=%2Chigher-position-rate) + shows how often a competitor’s offer got placed in a higher + position on the page than your offer. + + Cannot be filtered on in the 'WHERE' clause. + + This field is a member of `oneof`_ ``_higher_position_rate``. + """ + + date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=1, + message=date_pb2.Date, + ) + domain: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + is_your_domain: bool = proto.Field( + proto.BOOL, + number=3, + optional=True, + ) + report_country_code: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + report_category_id: int = proto.Field( + proto.INT64, + number=5, + optional=True, + ) + traffic_source: 'TrafficSource.TrafficSourceEnum' = proto.Field( + proto.ENUM, + number=6, + optional=True, + enum='TrafficSource.TrafficSourceEnum', + ) + rank: int = proto.Field( + proto.INT64, + number=7, + optional=True, + ) + ads_organic_ratio: float = proto.Field( + proto.DOUBLE, + number=8, + optional=True, + ) + page_overlap_rate: float = proto.Field( + proto.DOUBLE, + number=9, + optional=True, + ) + higher_position_rate: float = proto.Field( + proto.DOUBLE, + number=10, + optional=True, + ) + + +class CompetitiveVisibilityBenchmarkView(proto.Message): + r"""Fields available for query in + ``competitive_visibility_benchmark_view`` table. + + `Competitive + visibility `__ + report with the category benchmark. + + Values are only set for fields requested explicitly in the request's + search query. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + date (google.type.date_pb2.Date): + Date of this row. + + Required in the ``SELECT`` clause. A condition on ``date`` + is required in the ``WHERE`` clause. + report_country_code (str): + Country where impressions appeared. + + Required in the ``SELECT`` clause. A condition on + ``report_country_code`` is required in the ``WHERE`` clause. + + This field is a member of `oneof`_ ``_report_country_code``. + report_category_id (int): + Google product category ID to calculate the report for, + represented in `Google's product + taxonomy `__. + + Required in the ``SELECT`` clause. A condition on + ``report_category_id`` is required in the ``WHERE`` clause. + + This field is a member of `oneof`_ ``_report_category_id``. + traffic_source (google.shopping.merchant_reports_v1beta.types.TrafficSource.TrafficSourceEnum): + Traffic source of impressions. + + Required in the ``SELECT`` clause. + + This field is a member of `oneof`_ ``_traffic_source``. + your_domain_visibility_trend (float): + Change in visibility based on impressions for + your domain with respect to the start of the + selected time range (or first day with non-zero + impressions). + + Cannot be filtered on in the 'WHERE' clause. + + This field is a member of `oneof`_ ``_your_domain_visibility_trend``. + category_benchmark_visibility_trend (float): + Change in visibility based on impressions + with respect to the start of the selected time + range (or first day with non-zero impressions) + for a combined set of merchants with highest + visibility approximating the market. + + Cannot be filtered on in the 'WHERE' clause. + + This field is a member of `oneof`_ ``_category_benchmark_visibility_trend``. + """ + + date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=1, + message=date_pb2.Date, + ) + report_country_code: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + report_category_id: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + traffic_source: 'TrafficSource.TrafficSourceEnum' = proto.Field( + proto.ENUM, + number=4, + optional=True, + enum='TrafficSource.TrafficSourceEnum', + ) + your_domain_visibility_trend: float = proto.Field( + proto.DOUBLE, + number=5, + optional=True, + ) + category_benchmark_visibility_trend: float = proto.Field( + proto.DOUBLE, + number=6, + optional=True, + ) + + +class MarketingMethod(proto.Message): + r"""Marketing method used to promote your products on Google + (organic versus ads). + + """ + class MarketingMethodEnum(proto.Enum): + r"""Marketing method values. + + Values: + MARKETING_METHOD_ENUM_UNSPECIFIED (0): + Not specified. + ORGANIC (1): + Organic marketing. + ADS (2): + Ads-based marketing. + """ + MARKETING_METHOD_ENUM_UNSPECIFIED = 0 + ORGANIC = 1 + ADS = 2 + + +class ReportGranularity(proto.Message): + r"""Granularity of the Best sellers report. Best sellers reports + are computed over a week and a month timeframe. + + """ + class ReportGranularityEnum(proto.Enum): + r"""Report granularity values. + + Values: + REPORT_GRANULARITY_ENUM_UNSPECIFIED (0): + Not specified. + WEEKLY (1): + Report is computed over a week timeframe. + MONTHLY (2): + Report is computed over a month timeframe. + """ + REPORT_GRANULARITY_ENUM_UNSPECIFIED = 0 + WEEKLY = 1 + MONTHLY = 2 + + +class RelativeDemand(proto.Message): + r"""Relative demand of a product cluster or brand in the Best + sellers report. + + """ + class RelativeDemandEnum(proto.Enum): + r"""Relative demand values. + + Values: + RELATIVE_DEMAND_ENUM_UNSPECIFIED (0): + Not specified. + VERY_LOW (10): + Demand is 0-5% of the demand of the highest + ranked product cluster or brand. + LOW (20): + Demand is 6-10% of the demand of the highest + ranked product cluster or brand. + MEDIUM (30): + Demand is 11-20% of the demand of the highest + ranked product cluster or brand. + HIGH (40): + Demand is 21-50% of the demand of the highest + ranked product cluster or brand. + VERY_HIGH (50): + Demand is 51-100% of the demand of the + highest ranked product cluster or brand. + """ + RELATIVE_DEMAND_ENUM_UNSPECIFIED = 0 + VERY_LOW = 10 + LOW = 20 + MEDIUM = 30 + HIGH = 40 + VERY_HIGH = 50 + + +class RelativeDemandChangeType(proto.Message): + r"""Relative demand of a product cluster or brand in the Best + sellers report compared to the previous time period. + + """ + class RelativeDemandChangeTypeEnum(proto.Enum): + r"""Relative demand change type values. + + Values: + RELATIVE_DEMAND_CHANGE_TYPE_ENUM_UNSPECIFIED (0): + Not specified. + SINKER (1): + Relative demand is lower than the previous + time period. + FLAT (2): + Relative demand is equal to the previous time + period. + RISER (3): + Relative demand is higher than the previous + time period. + """ + RELATIVE_DEMAND_CHANGE_TYPE_ENUM_UNSPECIFIED = 0 + SINKER = 1 + FLAT = 2 + RISER = 3 + + +class TrafficSource(proto.Message): + r"""Traffic source of impressions in the Competitive visibility + report. + + """ + class TrafficSourceEnum(proto.Enum): + r"""Traffic source values. + + Values: + TRAFFIC_SOURCE_ENUM_UNSPECIFIED (0): + Not specified. + ORGANIC (1): + Organic traffic. + ADS (2): + Traffic from ads. + ALL (3): + Organic and ads traffic. + """ + TRAFFIC_SOURCE_ENUM_UNSPECIFIED = 0 + ORGANIC = 1 + ADS = 2 + ALL = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/mypy.ini b/owl-bot-staging/google-shopping-merchant-reports/v1beta/mypy.ini new file mode 100644 index 000000000000..574c5aed394b --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/noxfile.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/noxfile.py new file mode 100644 index 000000000000..da7084b1cfb2 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/noxfile.py @@ -0,0 +1,280 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 re +import shutil +import subprocess +import sys + + +import nox # type: ignore + +ALL_PYTHON = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", +] + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = 'google-shopping-merchant-reports' + +BLACK_VERSION = "black==22.3.0" +BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] +DEFAULT_PYTHON_VERSION = "3.13" + +nox.sessions = [ + "unit", + "cover", + "mypy", + "check_lower_bounds" + # exclude update_lower_bounds from default + "docs", + "blacken", + "lint", + "prerelease_deps", +] + +@nox.session(python=ALL_PYTHON) +@nox.parametrize( + "protobuf_implementation", + [ "python", "upb", "cpp" ], +) +def unit(session, protobuf_implementation): + """Run the unit test suite.""" + + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + session.skip("cpp implementation is not supported in python 3.11+") + + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + session.install('-e', '.', "-c", f"testing/constraints-{session.python}.txt") + + # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. + # The 'cpp' implementation requires Protobuf<4. + if protobuf_implementation == "cpp": + session.install("protobuf<4") + + session.run( + 'py.test', + '--quiet', + '--cov=google/shopping/merchant_reports_v1beta/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)), + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + +@nox.session(python=ALL_PYTHON[-1]) +@nox.parametrize( + "protobuf_implementation", + [ "python", "upb", "cpp" ], +) +def prerelease_deps(session, protobuf_implementation): + """Run the unit test suite against pre-release versions of dependencies.""" + + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + session.skip("cpp implementation is not supported in python 3.11+") + + # Install test environment dependencies + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + + # Install the package without dependencies + session.install('-e', '.', '--no-deps') + + # We test the minimum dependency versions using the minimum Python + # version so the lowest python runtime that we test has a corresponding constraints + # file, located at `testing/constraints--.txt`, which contains all of the + # dependencies and extras. + with open( + CURRENT_DIRECTORY + / "testing" + / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + session.install(*constraints_deps) + + prerel_deps = [ + "googleapis-common-protos", + "google-api-core", + "google-auth", + # Exclude grpcio!=1.67.0rc1 which does not support python 3.13 + "grpcio!=1.67.0rc1", + "grpcio-status", + "protobuf", + "proto-plus", + ] + + for dep in prerel_deps: + session.install("--pre", "--no-deps", "--upgrade", dep) + + # Remaining dependencies + other_deps = [ + "requests", + ] + session.install(*other_deps) + + # Print out prerelease package versions + + session.run("python", "-c", "import google.api_core; print(google.api_core.__version__)") + session.run("python", "-c", "import google.auth; print(google.auth.__version__)") + session.run("python", "-c", "import grpc; print(grpc.__version__)") + session.run( + "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" + ) + session.run( + "python", "-c", "import proto; print(proto.__version__)" + ) + + session.run( + 'py.test', + '--quiet', + '--cov=google/shopping/merchant_reports_v1beta/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)), + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +@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', + '-p', + '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, + ) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_async.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_async.py new file mode 100644 index 000000000000..6fa9200b9512 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 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-shopping-merchant-reports + + +# [START merchantapi_v1beta_generated_ReportService_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.shopping import merchant_reports_v1beta + + +async def sample_search(): + # Create a client + client = merchant_reports_v1beta.ReportServiceAsyncClient() + + # Initialize request argument(s) + request = merchant_reports_v1beta.SearchRequest( + parent="parent_value", + query="query_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END merchantapi_v1beta_generated_ReportService_Search_async] diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_sync.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_sync.py new file mode 100644 index 000000000000..11f591230812 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 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-shopping-merchant-reports + + +# [START merchantapi_v1beta_generated_ReportService_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.shopping import merchant_reports_v1beta + + +def sample_search(): + # Create a client + client = merchant_reports_v1beta.ReportServiceClient() + + # Initialize request argument(s) + request = merchant_reports_v1beta.SearchRequest( + parent="parent_value", + query="query_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END merchantapi_v1beta_generated_ReportService_Search_sync] diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1beta.json b/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1beta.json new file mode 100644 index 000000000000..55992b8a05a3 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1beta.json @@ -0,0 +1,176 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.shopping.merchant.reports.v1beta", + "version": "v1beta" + } + ], + "language": "PYTHON", + "name": "google-shopping-merchant-reports", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.shopping.merchant_reports_v1beta.ReportServiceAsyncClient", + "shortName": "ReportServiceAsyncClient" + }, + "fullName": "google.shopping.merchant_reports_v1beta.ReportServiceAsyncClient.search", + "method": { + "fullName": "google.shopping.merchant.reports.v1beta.ReportService.Search", + "service": { + "fullName": "google.shopping.merchant.reports.v1beta.ReportService", + "shortName": "ReportService" + }, + "shortName": "Search" + }, + "parameters": [ + { + "name": "request", + "type": "google.shopping.merchant_reports_v1beta.types.SearchRequest" + }, + { + "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.shopping.merchant_reports_v1beta.services.report_service.pagers.SearchAsyncPager", + "shortName": "search" + }, + "description": "Sample for Search", + "file": "merchantapi_v1beta_generated_report_service_search_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "merchantapi_v1beta_generated_ReportService_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": "merchantapi_v1beta_generated_report_service_search_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.shopping.merchant_reports_v1beta.ReportServiceClient", + "shortName": "ReportServiceClient" + }, + "fullName": "google.shopping.merchant_reports_v1beta.ReportServiceClient.search", + "method": { + "fullName": "google.shopping.merchant.reports.v1beta.ReportService.Search", + "service": { + "fullName": "google.shopping.merchant.reports.v1beta.ReportService", + "shortName": "ReportService" + }, + "shortName": "Search" + }, + "parameters": [ + { + "name": "request", + "type": "google.shopping.merchant_reports_v1beta.types.SearchRequest" + }, + { + "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.shopping.merchant_reports_v1beta.services.report_service.pagers.SearchPager", + "shortName": "search" + }, + "description": "Sample for Search", + "file": "merchantapi_v1beta_generated_report_service_search_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "merchantapi_v1beta_generated_ReportService_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": "merchantapi_v1beta_generated_report_service_search_sync.py" + } + ] +} diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/scripts/fixup_merchant_reports_v1beta_keywords.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/scripts/fixup_merchant_reports_v1beta_keywords.py new file mode 100644 index 000000000000..83db92c96848 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/scripts/fixup_merchant_reports_v1beta_keywords.py @@ -0,0 +1,176 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 merchant_reportsCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'search': ('parent', 'query', 'page_size', 'page_token', ), + } + + 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=merchant_reportsCallTransformer(), +): + """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 merchant_reports 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/google-shopping-merchant-reports/v1beta/setup.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/setup.py new file mode 100644 index 000000000000..434b659ca76d --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/setup.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 re + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = 'google-shopping-merchant-reports' + + +description = "Google Shopping Merchant Reports API client library" + +version = None + +with open(os.path.join(package_root, 'google/shopping/merchant_reports/gapic_version.py')) as fp: + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + assert (len(version_candidates) == 1) + version = version_candidates[0] + +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.1, <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.*", + # Exclude incompatible versions of `google-auth` + # See https://github.com/googleapis/google-cloud-python/issues/12364 + "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", + "proto-plus >= 1.22.3, <2.0.0dev", + "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", + "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", + "google-shopping-type >= 0.1.6, <1.0.0dev", +] +extras = { +} +url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-reports" + +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.find_namespace_packages() + if package.startswith("google") +] + +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", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + install_requires=dependencies, + extras_require=extras, + include_package_data=True, + zip_safe=False, +) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.10.txt b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.10.txt new file mode 100644 index 000000000000..4cae520d02b2 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.10.txt @@ -0,0 +1,7 @@ +# -*- 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 +google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.11.txt b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.11.txt new file mode 100644 index 000000000000..4cae520d02b2 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.11.txt @@ -0,0 +1,7 @@ +# -*- 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 +google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.12.txt b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.12.txt new file mode 100644 index 000000000000..4cae520d02b2 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.12.txt @@ -0,0 +1,7 @@ +# -*- 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 +google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.13.txt b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.13.txt new file mode 100644 index 000000000000..4cae520d02b2 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.13.txt @@ -0,0 +1,7 @@ +# -*- 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 +google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.7.txt b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.7.txt new file mode 100644 index 000000000000..130a0c0f80ab --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.7.txt @@ -0,0 +1,11 @@ +# 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.1 +google-auth==2.14.1 +proto-plus==1.22.3 +protobuf==3.20.2 +google-shopping-type==0.1.6 diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.8.txt b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.8.txt new file mode 100644 index 000000000000..4cae520d02b2 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.8.txt @@ -0,0 +1,7 @@ +# -*- 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 +google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.9.txt b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.9.txt new file mode 100644 index 000000000000..4cae520d02b2 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.9.txt @@ -0,0 +1,7 @@ +# -*- 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 +google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-reports/v1beta/tests/unit/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-reports/v1beta/tests/unit/gapic/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py new file mode 100644 index 000000000000..16d4b4d11c0d --- /dev/null +++ b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py @@ -0,0 +1,2389 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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, AsyncIterable +from google.protobuf import json_format +import json +import math +import pytest +from google.api_core import api_core_version +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 + +try: + from google.auth.aio import credentials as ga_credentials_async + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +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.api_core import retry as retries +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.shopping.merchant_reports_v1beta.services.report_service import ReportServiceAsyncClient +from google.shopping.merchant_reports_v1beta.services.report_service import ReportServiceClient +from google.shopping.merchant_reports_v1beta.services.report_service import pagers +from google.shopping.merchant_reports_v1beta.services.report_service import transports +from google.shopping.merchant_reports_v1beta.types import reports +import google.auth + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + +# 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 + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return "test.{UNIVERSE_DOMAIN}" if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) else client._DEFAULT_ENDPOINT_TEMPLATE + + +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 ReportServiceClient._get_default_mtls_endpoint(None) is None + assert ReportServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ReportServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ReportServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ReportServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ReportServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + +def test__read_environment_variables(): + assert ReportServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert ReportServiceClient._read_environment_variables() == (True, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert ReportServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError) as excinfo: + ReportServiceClient._read_environment_variables() + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert ReportServiceClient._read_environment_variables() == (False, "never", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert ReportServiceClient._read_environment_variables() == (False, "always", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert ReportServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + ReportServiceClient._read_environment_variables() + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert ReportServiceClient._read_environment_variables() == (False, "auto", "foo.com") + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert ReportServiceClient._get_client_cert_source(None, False) is None + assert ReportServiceClient._get_client_cert_source(mock_provided_cert_source, False) is None + assert ReportServiceClient._get_client_cert_source(mock_provided_cert_source, True) == mock_provided_cert_source + + 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_default_cert_source): + assert ReportServiceClient._get_client_cert_source(None, True) is mock_default_cert_source + assert ReportServiceClient._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source + +@mock.patch.object(ReportServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceClient)) +@mock.patch.object(ReportServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceAsyncClient)) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = ReportServiceClient._DEFAULT_UNIVERSE + default_endpoint = ReportServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) + mock_universe = "bar.com" + mock_endpoint = ReportServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) + + assert ReportServiceClient._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override + assert ReportServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == ReportServiceClient.DEFAULT_MTLS_ENDPOINT + assert ReportServiceClient._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint + assert ReportServiceClient._get_api_endpoint(None, None, default_universe, "always") == ReportServiceClient.DEFAULT_MTLS_ENDPOINT + assert ReportServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == ReportServiceClient.DEFAULT_MTLS_ENDPOINT + assert ReportServiceClient._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint + assert ReportServiceClient._get_api_endpoint(None, None, default_universe, "never") == default_endpoint + + with pytest.raises(MutualTLSChannelError) as excinfo: + ReportServiceClient._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto") + assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com." + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ReportServiceClient._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain + assert ReportServiceClient._get_universe_domain(None, universe_domain_env) == universe_domain_env + assert ReportServiceClient._get_universe_domain(None, None) == ReportServiceClient._DEFAULT_UNIVERSE + + with pytest.raises(ValueError) as excinfo: + ReportServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc"), + (ReportServiceClient, transports.ReportServiceRestTransport, "rest"), +]) +def test__validate_universe_domain(client_class, transport_class, transport_name): + client = client_class( + transport=transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + ) + assert client._validate_universe_domain() == True + + # Test the case when universe is already validated. + assert client._validate_universe_domain() == True + + if transport_name == "grpc": + # Test the case where credentials are provided by the + # `local_channel_credentials`. The default universes in both match. + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + client = client_class(transport=transport_class(channel=channel)) + assert client._validate_universe_domain() == True + + # Test the case where credentials do not exist: e.g. a transport is provided + # with no credentials. Validation should still succeed because there is no + # mismatch with non-existent credentials. + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + transport=transport_class(channel=channel) + transport._credentials = None + client = client_class(transport=transport) + assert client._validate_universe_domain() == True + + # TODO: This is needed to cater for older versions of google-auth + # Make this test unconditional once the minimum supported version of + # google-auth becomes 2.23.0 or higher. + google_auth_major, google_auth_minor = [int(part) for part in google.auth.__version__.split(".")[0:2]] + if google_auth_major > 2 or (google_auth_major == 2 and google_auth_minor >= 23): + credentials = ga_credentials.AnonymousCredentials() + credentials._universe_domain = "foo.com" + # Test the case when there is a universe mismatch from the credentials. + client = client_class( + transport=transport_class(credentials=credentials) + ) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert str(excinfo.value) == "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (foo.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + + # Test the case when there is a universe mismatch from the client. + # + # TODO: Make this test unconditional once the minimum supported version of + # google-api-core becomes 2.15.0 or higher. + api_core_major, api_core_minor = [int(part) for part in api_core_version.__version__.split(".")[0:2]] + if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 15): + client = client_class(client_options={"universe_domain": "bar.com"}, transport=transport_class(credentials=ga_credentials.AnonymousCredentials(),)) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert str(excinfo.value) == "The configured universe domain (bar.com) does not match the universe domain found in the credentials (googleapis.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + + # Test that ValueError is raised if universe_domain is provided via client options and credentials is None + with pytest.raises(ValueError): + client._compare_universes("foo.bar", None) + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ReportServiceClient, "grpc"), + (ReportServiceAsyncClient, "grpc_asyncio"), + (ReportServiceClient, "rest"), +]) +def test_report_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 == ( + 'merchantapi.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://merchantapi.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ReportServiceGrpcTransport, "grpc"), + (transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ReportServiceRestTransport, "rest"), +]) +def test_report_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", [ + (ReportServiceClient, "grpc"), + (ReportServiceAsyncClient, "grpc_asyncio"), + (ReportServiceClient, "rest"), +]) +def test_report_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 == ( + 'merchantapi.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://merchantapi.googleapis.com' + ) + + +def test_report_service_client_get_transport_class(): + transport = ReportServiceClient.get_transport_class() + available_transports = [ + transports.ReportServiceGrpcTransport, + transports.ReportServiceRestTransport, + ] + assert transport in available_transports + + transport = ReportServiceClient.get_transport_class("grpc") + assert transport == transports.ReportServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc"), + (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ReportServiceClient, transports.ReportServiceRestTransport, "rest"), +]) +@mock.patch.object(ReportServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceClient)) +@mock.patch.object(ReportServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceAsyncClient)) +def test_report_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(ReportServiceClient, '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(ReportServiceClient, '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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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) as excinfo: + client = client_class(transport=transport_name) + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + # 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) as excinfo: + client = client_class(transport=transport_name) + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + + # 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + 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", [ + (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc", "true"), + (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc", "false"), + (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ReportServiceClient, transports.ReportServiceRestTransport, "rest", "true"), + (ReportServiceClient, transports.ReportServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(ReportServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceClient)) +@mock.patch.object(ReportServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_report_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) + 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) + 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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", [ + ReportServiceClient, ReportServiceAsyncClient +]) +@mock.patch.object(ReportServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ReportServiceClient)) +@mock.patch.object(ReportServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ReportServiceAsyncClient)) +def test_report_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 + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + +@pytest.mark.parametrize("client_class", [ + ReportServiceClient, ReportServiceAsyncClient +]) +@mock.patch.object(ReportServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceClient)) +@mock.patch.object(ReportServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceAsyncClient)) +def test_report_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = ReportServiceClient._DEFAULT_UNIVERSE + default_endpoint = ReportServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) + mock_universe = "bar.com" + mock_endpoint = ReportServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel"): + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=api_override) + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + else: + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == (mock_endpoint if universe_exists else default_endpoint) + assert client.universe_domain == (mock_universe if universe_exists else default_universe) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc"), + (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ReportServiceClient, transports.ReportServiceRestTransport, "rest"), +]) +def test_report_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + 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", [ + (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc", grpc_helpers), + (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ReportServiceClient, transports.ReportServiceRestTransport, "rest", None), +]) +def test_report_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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_report_service_client_client_options_from_dict(): + with mock.patch('google.shopping.merchant_reports_v1beta.services.report_service.transports.ReportServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ReportServiceClient( + 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", [ + (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc", grpc_helpers), + (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_report_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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( + "merchantapi.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/content', +), + scopes=None, + default_host="merchantapi.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + reports.SearchRequest, + dict, +]) +def test_search(request_type, transport: str = 'grpc'): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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 = reports.SearchResponse( + next_page_token='next_page_token_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] + request = reports.SearchRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_search_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = reports.SearchRequest( + parent='parent_value', + query='query_value', + page_token='page_token_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.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.search(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == reports.SearchRequest( + parent='parent_value', + query='query_value', + page_token='page_token_value', + ) + +def test_search_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.search in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.search] = mock_rpc + request = {} + client.search(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.search(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_search_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = ReportServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.search in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.search] = mock_rpc + + request = {} + await client.search(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.search(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_search_async(transport: str = 'grpc_asyncio', request_type=reports.SearchRequest): + client = ReportServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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(reports.SearchResponse( + next_page_token='next_page_token_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] + request = reports.SearchRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_search_async_from_dict(): + await test_search_async(request_type=dict) + +def test_search_field_headers(): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = reports.SearchRequest() + + request.parent = 'parent_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 = reports.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', + 'parent=parent_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_search_field_headers_async(): + client = ReportServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = reports.SearchRequest() + + request.parent = 'parent_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(reports.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', + 'parent=parent_value', + ) in kw['metadata'] + + +def test_search_flattened(): + client = ReportServiceClient( + 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__') as call: + # Designate an appropriate return value for the call. + call.return_value = reports.SearchResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.search( + 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_search_flattened_error(): + client = ReportServiceClient( + 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.search( + reports.SearchRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_search_flattened_async(): + client = ReportServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = reports.SearchResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(reports.SearchResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.search( + 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_search_flattened_error_async(): + client = ReportServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.search( + reports.SearchRequest(), + parent='parent_value', + ) + + +def test_search_pager(transport_name: str = "grpc"): + client = ReportServiceClient( + 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 = ( + reports.SearchResponse( + results=[ + reports.ReportRow(), + reports.ReportRow(), + reports.ReportRow(), + ], + next_page_token='abc', + ), + reports.SearchResponse( + results=[], + next_page_token='def', + ), + reports.SearchResponse( + results=[ + reports.ReportRow(), + ], + next_page_token='ghi', + ), + reports.SearchResponse( + results=[ + reports.ReportRow(), + reports.ReportRow(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.search(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, reports.ReportRow) + for i in results) +def test_search_pages(transport_name: str = "grpc"): + client = ReportServiceClient( + 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 = ( + reports.SearchResponse( + results=[ + reports.ReportRow(), + reports.ReportRow(), + reports.ReportRow(), + ], + next_page_token='abc', + ), + reports.SearchResponse( + results=[], + next_page_token='def', + ), + reports.SearchResponse( + results=[ + reports.ReportRow(), + ], + next_page_token='ghi', + ), + reports.SearchResponse( + results=[ + reports.ReportRow(), + reports.ReportRow(), + ], + ), + 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 = ReportServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = ( + reports.SearchResponse( + results=[ + reports.ReportRow(), + reports.ReportRow(), + reports.ReportRow(), + ], + next_page_token='abc', + ), + reports.SearchResponse( + results=[], + next_page_token='def', + ), + reports.SearchResponse( + results=[ + reports.ReportRow(), + ], + next_page_token='ghi', + ), + reports.SearchResponse( + results=[ + reports.ReportRow(), + reports.ReportRow(), + ], + ), + 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, reports.ReportRow) + for i in responses) + + +@pytest.mark.asyncio +async def test_search_async_pages(): + client = ReportServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # 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 = ( + reports.SearchResponse( + results=[ + reports.ReportRow(), + reports.ReportRow(), + reports.ReportRow(), + ], + next_page_token='abc', + ), + reports.SearchResponse( + results=[], + next_page_token='def', + ), + reports.SearchResponse( + results=[ + reports.ReportRow(), + ], + next_page_token='ghi', + ), + reports.SearchResponse( + results=[ + reports.ReportRow(), + reports.ReportRow(), + ], + ), + 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 + + +def test_search_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.search in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.search] = mock_rpc + + request = {} + client.search(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.search(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_search_rest_required_fields(request_type=reports.SearchRequest): + transport_class = transports.ReportServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["query"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + 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["parent"] = 'parent_value' + jsonified_request["query"] = 'query_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 "parent" in jsonified_request + assert jsonified_request["parent"] == 'parent_value' + assert "query" in jsonified_request + assert jsonified_request["query"] == 'query_value' + + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = reports.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 + + # Convert return value to protobuf type + return_value = reports.SearchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.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.ReportServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.search._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "query", ))) + + +def test_search_rest_flattened(): + client = ReportServiceClient( + 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 = reports.SearchResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'accounts/sample1'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = reports.SearchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.search(**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/reports/v1beta/{parent=accounts/*}/reports:search" % client.transport._host, args[1]) + + +def test_search_rest_flattened_error(transport: str = 'rest'): + client = ReportServiceClient( + 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.search( + reports.SearchRequest(), + parent='parent_value', + ) + + +def test_search_rest_pager(transport: str = 'rest'): + client = ReportServiceClient( + 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 = ( + reports.SearchResponse( + results=[ + reports.ReportRow(), + reports.ReportRow(), + reports.ReportRow(), + ], + next_page_token='abc', + ), + reports.SearchResponse( + results=[], + next_page_token='def', + ), + reports.SearchResponse( + results=[ + reports.ReportRow(), + ], + next_page_token='ghi', + ), + reports.SearchResponse( + results=[ + reports.ReportRow(), + reports.ReportRow(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(reports.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 = {'parent': 'accounts/sample1'} + + pager = client.search(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, reports.ReportRow) + 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.ReportServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ReportServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ReportServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ReportServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ReportServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ReportServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ReportServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ReportServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ReportServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ReportServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ReportServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ReportServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ReportServiceGrpcTransport, + transports.ReportServiceGrpcAsyncIOTransport, + transports.ReportServiceRestTransport, +]) +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() + +def test_transport_kind_grpc(): + transport = ReportServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_empty_call_grpc(): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__') as call: + call.return_value = reports.SearchResponse() + client.search(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = reports.SearchRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = ReportServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = ReportServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_search_empty_call_grpc_asyncio(): + client = ReportServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, 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(reports.SearchResponse( + next_page_token='next_page_token_value', + )) + await client.search(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = reports.SearchRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = ReportServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_search_rest_bad_request(request_type=reports.SearchRequest): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'parent': 'accounts/sample1'} + 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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.search(request) + + +@pytest.mark.parametrize("request_type", [ + reports.SearchRequest, + dict, +]) +def test_search_rest_call_success(request_type): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'accounts/sample1'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = reports.SearchResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = reports.SearchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.search(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_search_rest_interceptors(null_interceptor): + transport = transports.ReportServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ReportServiceRestInterceptor(), + ) + client = ReportServiceClient(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.ReportServiceRestInterceptor, "post_search") as post, \ + mock.patch.object(transports.ReportServiceRestInterceptor, "pre_search") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = reports.SearchRequest.pb(reports.SearchRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = reports.SearchResponse.to_json(reports.SearchResponse()) + req.return_value.content = return_value + + request = reports.SearchRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = reports.SearchResponse() + + client.search(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + +def test_initialize_client_w_rest(): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_empty_call_rest(): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__') as call: + client.search(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = reports.SearchRequest() + + assert args[0] == request_msg + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ReportServiceGrpcTransport, + ) + +def test_report_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ReportServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_report_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.shopping.merchant_reports_v1beta.services.report_service.transports.ReportServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ReportServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'search', + ) + 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_report_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.shopping.merchant_reports_v1beta.services.report_service.transports.ReportServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ReportServiceTransport( + 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/content', +), + quota_project_id="octopus", + ) + + +def test_report_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.shopping.merchant_reports_v1beta.services.report_service.transports.ReportServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ReportServiceTransport() + adc.assert_called_once() + + +def test_report_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) + ReportServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/content', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ReportServiceGrpcTransport, + transports.ReportServiceGrpcAsyncIOTransport, + ], +) +def test_report_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/content',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ReportServiceGrpcTransport, + transports.ReportServiceGrpcAsyncIOTransport, + transports.ReportServiceRestTransport, + ], +) +def test_report_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.ReportServiceGrpcTransport, grpc_helpers), + (transports.ReportServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_report_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( + "merchantapi.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/content', +), + scopes=["1", "2"], + default_host="merchantapi.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ReportServiceGrpcTransport, transports.ReportServiceGrpcAsyncIOTransport]) +def test_report_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_report_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.ReportServiceRestTransport ( + 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_report_service_host_no_port(transport_name): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='merchantapi.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'merchantapi.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://merchantapi.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_report_service_host_with_port(transport_name): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='merchantapi.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'merchantapi.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://merchantapi.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_report_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ReportServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ReportServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.search._session + session2 = client2.transport.search._session + assert session1 != session2 +def test_report_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ReportServiceGrpcTransport( + 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_report_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ReportServiceGrpcAsyncIOTransport( + 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.ReportServiceGrpcTransport, transports.ReportServiceGrpcAsyncIOTransport]) +def test_report_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.ReportServiceGrpcTransport, transports.ReportServiceGrpcAsyncIOTransport]) +def test_report_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_common_billing_account_path(): + billing_account = "squid" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ReportServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = ReportServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ReportServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "whelk" + expected = "folders/{folder}".format(folder=folder, ) + actual = ReportServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = ReportServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ReportServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "oyster" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ReportServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = ReportServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ReportServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "cuttlefish" + expected = "projects/{project}".format(project=project, ) + actual = ReportServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = ReportServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ReportServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ReportServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = ReportServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ReportServiceClient.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.ReportServiceTransport, '_prep_wrapped_messages') as prep: + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ReportServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ReportServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_grpc(): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc" + ) + with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = ReportServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio" + ) + with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close_rest(): + client = ReportServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + with mock.patch.object(type(getattr(client.transport, "_session")), "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 = ReportServiceClient( + 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", [ + (ReportServiceClient, transports.ReportServiceGrpcTransport), + (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport), +]) +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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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/google-shopping-type/google-shopping-type-py/.coveragerc b/owl-bot-staging/google-shopping-type/google-shopping-type-py/.coveragerc new file mode 100644 index 000000000000..00a864f27048 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/shopping/type/__init__.py + google/shopping/type/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/google-shopping-type/google-shopping-type-py/.flake8 b/owl-bot-staging/google-shopping-type/google-shopping-type-py/.flake8 new file mode 100644 index 000000000000..29227d4cf419 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/.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/google-shopping-type/google-shopping-type-py/MANIFEST.in b/owl-bot-staging/google-shopping-type/google-shopping-type-py/MANIFEST.in new file mode 100644 index 000000000000..d7887f950009 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include google/shopping/type *.py +recursive-include google/shopping/type *.py diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/README.rst b/owl-bot-staging/google-shopping-type/google-shopping-type-py/README.rst new file mode 100644 index 000000000000..ad987a05fd48 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/README.rst @@ -0,0 +1,49 @@ +Python Client for Google Shopping Type 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 Shopping Type 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/google-shopping-type/google-shopping-type-py/docs/_static/custom.css b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/_static/custom.css new file mode 100644 index 000000000000..06423be0b592 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/_static/custom.css @@ -0,0 +1,3 @@ +dl.field-list > dt { + min-width: 100px +} diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/conf.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/conf.py new file mode 100644 index 000000000000..ae5cf46489f7 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/conf.py @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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-shopping-type 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-shopping-type" +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 Shopping 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-shopping-type-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-shopping-type.tex", + u"google-shopping-type 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-shopping-type", + u"Google Shopping Type 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-shopping-type", + u"google-shopping-type Documentation", + author, + "google-shopping-type", + "GAPIC library for Google Shopping Type 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/google-shopping-type/google-shopping-type-py/docs/index.rst b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/index.rst new file mode 100644 index 000000000000..2605a730d688 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + type/services_ + type/types_ diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/services_.rst b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/services_.rst new file mode 100644 index 000000000000..064d8549804a --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/services_.rst @@ -0,0 +1,4 @@ +Services for Google Shopping Type API +====================================== +.. toctree:: + :maxdepth: 2 diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/types_.rst b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/types_.rst new file mode 100644 index 000000000000..ee93d33ec032 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/types_.rst @@ -0,0 +1,6 @@ +Types for Google Shopping Type API +=================================== + +.. automodule:: google.shopping.type.types + :members: + :show-inheritance: diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/__init__.py new file mode 100644 index 000000000000..81e1b2cc88a3 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.shopping.type import gapic_version as package_version + +__version__ = package_version.__version__ + + + +from .types.types import Channel +from .types.types import CustomAttribute +from .types.types import Destination +from .types.types import Price +from .types.types import ReportingContext +from .types.types import Weight + +__all__ = ( +'Channel', +'CustomAttribute', +'Destination', +'Price', +'ReportingContext', +'Weight', +) diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_metadata.json b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_metadata.json new file mode 100644 index 000000000000..284d1a73cfda --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_metadata.json @@ -0,0 +1,7 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.shopping.type", + "protoPackage": "google.shopping.type", + "schema": "1.0" +} diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_version.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_version.py new file mode 100644 index 000000000000..558c8aab67c5 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-type/google-shopping-type-py/google/shopping/type/py.typed b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/py.typed new file mode 100644 index 000000000000..5c0a2eb8cab8 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-shopping-type package uses inline types. diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/services/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/services/__init__.py new file mode 100644 index 000000000000..8f6cf068242c --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-type/google-shopping-type-py/google/shopping/type/types/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/__init__.py new file mode 100644 index 000000000000..4c5ee0230744 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/__init__.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .types import ( + Channel, + CustomAttribute, + Destination, + Price, + ReportingContext, + Weight, +) + +__all__ = ( + 'Channel', + 'CustomAttribute', + 'Destination', + 'Price', + 'ReportingContext', + 'Weight', +) diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/types.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/types.py new file mode 100644 index 000000000000..e860ce590cf6 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/types.py @@ -0,0 +1,297 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.shopping.type', + manifest={ + 'Weight', + 'Price', + 'CustomAttribute', + 'Destination', + 'ReportingContext', + 'Channel', + }, +) + + +class Weight(proto.Message): + r"""The weight represented as the value in string and the unit. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + amount_micros (int): + Required. The weight represented as a number + in micros (1 million micros is an equivalent to + one's currency standard unit, for example, 1 kg + = 1000000 micros). + This field can also be set as infinity by + setting to -1. This field only support -1 and + positive value. + + This field is a member of `oneof`_ ``_amount_micros``. + unit (google.shopping.type.types.Weight.WeightUnit): + Required. The weight unit. + Acceptable values are: kg and lb + """ + class WeightUnit(proto.Enum): + r"""The weight unit. + + Values: + WEIGHT_UNIT_UNSPECIFIED (0): + unit unspecified + POUND (1): + lb unit. + KILOGRAM (2): + kg unit. + """ + WEIGHT_UNIT_UNSPECIFIED = 0 + POUND = 1 + KILOGRAM = 2 + + amount_micros: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + unit: WeightUnit = proto.Field( + proto.ENUM, + number=2, + enum=WeightUnit, + ) + + +class Price(proto.Message): + r"""The price represented as a number and currency. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + amount_micros (int): + The price represented as a number in micros + (1 million micros is an equivalent to one's + currency standard unit, for example, 1 USD = + 1000000 micros). + + This field is a member of `oneof`_ ``_amount_micros``. + currency_code (str): + The currency of the price using three-letter acronyms + according to `ISO + 4217 `__. + + This field is a member of `oneof`_ ``_currency_code``. + """ + + amount_micros: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + currency_code: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + + +class CustomAttribute(proto.Message): + r"""A message that represents custom attributes. Exactly one of + ``value`` or ``group_values`` must not be empty. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + The name of the attribute. + + This field is a member of `oneof`_ ``_name``. + value (str): + The value of the attribute. If ``value`` is not empty, + ``group_values`` must be empty. + + This field is a member of `oneof`_ ``_value``. + group_values (MutableSequence[google.shopping.type.types.CustomAttribute]): + Subattributes within this attribute group. If + ``group_values`` is not empty, ``value`` must be empty. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + value: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + group_values: MutableSequence['CustomAttribute'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='CustomAttribute', + ) + + +class Destination(proto.Message): + r"""Destinations available for a product. + + Destinations are used in Merchant Center to allow you to control + where the products from your data feed should be displayed. + + """ + class DestinationEnum(proto.Enum): + r"""Destination values. + + Values: + DESTINATION_ENUM_UNSPECIFIED (0): + Not specified. + SHOPPING_ADS (1): + `Shopping + ads `__. + DISPLAY_ADS (2): + `Display + ads `__. + LOCAL_INVENTORY_ADS (3): + `Local inventory + ads `__. + FREE_LISTINGS (4): + `Free + listings `__. + FREE_LOCAL_LISTINGS (5): + `Free local product + listings `__. + YOUTUBE_SHOPPING (6): + `YouTube + Shopping `__. + """ + DESTINATION_ENUM_UNSPECIFIED = 0 + SHOPPING_ADS = 1 + DISPLAY_ADS = 2 + LOCAL_INVENTORY_ADS = 3 + FREE_LISTINGS = 4 + FREE_LOCAL_LISTINGS = 5 + YOUTUBE_SHOPPING = 6 + + +class ReportingContext(proto.Message): + r"""Reporting contexts that your account and product issues apply to. + + Reporting contexts are groups of surfaces and formats for product + results on Google. They can represent the entire destination (for + example, `Shopping + ads `__) or a + subset of formats within a destination (for example, `Demand Gen + ads `__). + + """ + class ReportingContextEnum(proto.Enum): + r"""Reporting context values. + + Values: + REPORTING_CONTEXT_ENUM_UNSPECIFIED (0): + Not specified. + SHOPPING_ADS (1): + `Shopping + ads `__. + DISCOVERY_ADS (2): + Deprecated: Use ``DEMAND_GEN_ADS`` instead. `Discovery and + Demand Gen + ads `__. + DEMAND_GEN_ADS (13): + `Demand Gen + ads `__. + DEMAND_GEN_ADS_DISCOVER_SURFACE (14): + `Demand Gen ads on Discover + surface `__. + VIDEO_ADS (3): + `Video + ads `__. + DISPLAY_ADS (4): + `Display + ads `__. + LOCAL_INVENTORY_ADS (5): + `Local inventory + ads `__. + VEHICLE_INVENTORY_ADS (6): + `Vehicle inventory + ads `__. + FREE_LISTINGS (7): + `Free product + listings `__. + FREE_LOCAL_LISTINGS (8): + `Free local product + listings `__. + FREE_LOCAL_VEHICLE_LISTINGS (9): + `Free local vehicle + listings `__. + YOUTUBE_SHOPPING (10): + `YouTube + Shopping `__. + CLOUD_RETAIL (11): + `Cloud + retail `__. + LOCAL_CLOUD_RETAIL (12): + `Local cloud + retail `__. + """ + REPORTING_CONTEXT_ENUM_UNSPECIFIED = 0 + SHOPPING_ADS = 1 + DISCOVERY_ADS = 2 + DEMAND_GEN_ADS = 13 + DEMAND_GEN_ADS_DISCOVER_SURFACE = 14 + VIDEO_ADS = 3 + DISPLAY_ADS = 4 + LOCAL_INVENTORY_ADS = 5 + VEHICLE_INVENTORY_ADS = 6 + FREE_LISTINGS = 7 + FREE_LOCAL_LISTINGS = 8 + FREE_LOCAL_VEHICLE_LISTINGS = 9 + YOUTUBE_SHOPPING = 10 + CLOUD_RETAIL = 11 + LOCAL_CLOUD_RETAIL = 12 + + +class Channel(proto.Message): + r"""`Channel `__ of + a product. + + Channel is used to distinguish between online and local products. + + """ + class ChannelEnum(proto.Enum): + r"""Channel values. + + Values: + CHANNEL_ENUM_UNSPECIFIED (0): + Not specified. + ONLINE (1): + Online product. + LOCAL (2): + Local product. + """ + CHANNEL_ENUM_UNSPECIFIED = 0 + ONLINE = 1 + LOCAL = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/mypy.ini b/owl-bot-staging/google-shopping-type/google-shopping-type-py/mypy.ini new file mode 100644 index 000000000000..574c5aed394b --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/noxfile.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/noxfile.py new file mode 100644 index 000000000000..1011be60232e --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/noxfile.py @@ -0,0 +1,280 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 re +import shutil +import subprocess +import sys + + +import nox # type: ignore + +ALL_PYTHON = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", +] + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = 'google-shopping-type' + +BLACK_VERSION = "black==22.3.0" +BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] +DEFAULT_PYTHON_VERSION = "3.13" + +nox.sessions = [ + "unit", + "cover", + "mypy", + "check_lower_bounds" + # exclude update_lower_bounds from default + "docs", + "blacken", + "lint", + "prerelease_deps", +] + +@nox.session(python=ALL_PYTHON) +@nox.parametrize( + "protobuf_implementation", + [ "python", "upb", "cpp" ], +) +def unit(session, protobuf_implementation): + """Run the unit test suite.""" + + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + session.skip("cpp implementation is not supported in python 3.11+") + + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + session.install('-e', '.', "-c", f"testing/constraints-{session.python}.txt") + + # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. + # The 'cpp' implementation requires Protobuf<4. + if protobuf_implementation == "cpp": + session.install("protobuf<4") + + session.run( + 'py.test', + '--quiet', + '--cov=google/shopping/type/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)), + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + +@nox.session(python=ALL_PYTHON[-1]) +@nox.parametrize( + "protobuf_implementation", + [ "python", "upb", "cpp" ], +) +def prerelease_deps(session, protobuf_implementation): + """Run the unit test suite against pre-release versions of dependencies.""" + + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + session.skip("cpp implementation is not supported in python 3.11+") + + # Install test environment dependencies + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + + # Install the package without dependencies + session.install('-e', '.', '--no-deps') + + # We test the minimum dependency versions using the minimum Python + # version so the lowest python runtime that we test has a corresponding constraints + # file, located at `testing/constraints--.txt`, which contains all of the + # dependencies and extras. + with open( + CURRENT_DIRECTORY + / "testing" + / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + session.install(*constraints_deps) + + prerel_deps = [ + "googleapis-common-protos", + "google-api-core", + "google-auth", + # Exclude grpcio!=1.67.0rc1 which does not support python 3.13 + "grpcio!=1.67.0rc1", + "grpcio-status", + "protobuf", + "proto-plus", + ] + + for dep in prerel_deps: + session.install("--pre", "--no-deps", "--upgrade", dep) + + # Remaining dependencies + other_deps = [ + "requests", + ] + session.install(*other_deps) + + # Print out prerelease package versions + + session.run("python", "-c", "import google.api_core; print(google.api_core.__version__)") + session.run("python", "-c", "import google.auth; print(google.auth.__version__)") + session.run("python", "-c", "import grpc; print(grpc.__version__)") + session.run( + "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" + ) + session.run( + "python", "-c", "import proto; print(proto.__version__)" + ) + + session.run( + 'py.test', + '--quiet', + '--cov=google/shopping/type/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)), + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +@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', + '-p', + '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, + ) diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/scripts/fixup_type_keywords.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/scripts/fixup_type_keywords.py new file mode 100644 index 000000000000..bae51b8ecbd3 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/scripts/fixup_type_keywords.py @@ -0,0 +1,175 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 typeCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + } + + 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=typeCallTransformer(), +): + """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 type 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/google-shopping-type/google-shopping-type-py/setup.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/setup.py new file mode 100644 index 000000000000..99bf51929d58 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/setup.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 re + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = 'google-shopping-type' + + +description = "Google Shopping Type API client library" + +version = None + +with open(os.path.join(package_root, 'google/shopping/type/gapic_version.py')) as fp: + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + assert (len(version_candidates) == 1) + version = version_candidates[0] + +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.1, <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.*", + # Exclude incompatible versions of `google-auth` + # See https://github.com/googleapis/google-cloud-python/issues/12364 + "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", + "proto-plus >= 1.22.3, <2.0.0dev", + "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", + "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", +] +extras = { +} +url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-type" + +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.find_namespace_packages() + if package.startswith("google") +] + +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", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + install_requires=dependencies, + extras_require=extras, + include_package_data=True, + zip_safe=False, +) diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.10.txt b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.10.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/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/google-shopping-type/google-shopping-type-py/testing/constraints-3.11.txt b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.11.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/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/google-shopping-type/google-shopping-type-py/testing/constraints-3.12.txt b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.12.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/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/google-shopping-type/google-shopping-type-py/testing/constraints-3.13.txt b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.13.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.13.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/google-shopping-type/google-shopping-type-py/testing/constraints-3.7.txt b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.7.txt new file mode 100644 index 000000000000..fc812592b0ee --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.7.txt @@ -0,0 +1,10 @@ +# 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.1 +google-auth==2.14.1 +proto-plus==1.22.3 +protobuf==3.20.2 diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.8.txt b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.8.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/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/google-shopping-type/google-shopping-type-py/testing/constraints-3.9.txt b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.9.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/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/google-shopping-type/google-shopping-type-py/tests/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-type/google-shopping-type-py/tests/unit/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-type/google-shopping-type-py/tests/unit/gapic/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/gapic/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/gapic/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/google-shopping-type/google-shopping-type-py/tests/unit/gapic/type/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/gapic/type/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/gapic/type/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/grafeas/v1/.coveragerc b/owl-bot-staging/grafeas/v1/.coveragerc new file mode 100644 index 000000000000..4e55acc51c44 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + grafeas/grafeas/__init__.py + grafeas/grafeas/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/grafeas/v1/.flake8 b/owl-bot-staging/grafeas/v1/.flake8 new file mode 100644 index 000000000000..29227d4cf419 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/.flake8 @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by synthtool. DO NOT EDIT! +[flake8] +ignore = E203, E266, E501, W503 +exclude = + # Exclude generated code. + **/proto/** + **/gapic/** + **/services/** + **/types/** + *_pb2.py + + # Standard linting exemptions. + **/.nox/** + __pycache__, + .git, + *.pyc, + conf.py diff --git a/owl-bot-staging/grafeas/v1/MANIFEST.in b/owl-bot-staging/grafeas/v1/MANIFEST.in new file mode 100644 index 000000000000..075904e53516 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include grafeas/grafeas *.py +recursive-include grafeas/grafeas_v1 *.py diff --git a/owl-bot-staging/grafeas/v1/README.rst b/owl-bot-staging/grafeas/v1/README.rst new file mode 100644 index 000000000000..0f879492ca1d --- /dev/null +++ b/owl-bot-staging/grafeas/v1/README.rst @@ -0,0 +1,49 @@ +Python Client for Grafeas Grafeas 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 Grafeas Grafeas 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/grafeas/v1/docs/_static/custom.css b/owl-bot-staging/grafeas/v1/docs/_static/custom.css new file mode 100644 index 000000000000..06423be0b592 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/docs/_static/custom.css @@ -0,0 +1,3 @@ +dl.field-list > dt { + min-width: 100px +} diff --git a/owl-bot-staging/grafeas/v1/docs/conf.py b/owl-bot-staging/grafeas/v1/docs/conf.py new file mode 100644 index 000000000000..e43817cf2e74 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/docs/conf.py @@ -0,0 +1,376 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# grafeas 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"grafeas" +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": "Grafeas 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 = "grafeas-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, + "grafeas.tex", + u"grafeas 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, + "grafeas", + u"Grafeas Grafeas 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, + "grafeas", + u"grafeas Documentation", + author, + "grafeas", + "GAPIC library for Grafeas Grafeas 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/grafeas/v1/docs/grafeas_v1/grafeas.rst b/owl-bot-staging/grafeas/v1/docs/grafeas_v1/grafeas.rst new file mode 100644 index 000000000000..7339fabecaee --- /dev/null +++ b/owl-bot-staging/grafeas/v1/docs/grafeas_v1/grafeas.rst @@ -0,0 +1,10 @@ +Grafeas +------------------------- + +.. automodule:: grafeas.grafeas_v1.services.grafeas + :members: + :inherited-members: + +.. automodule:: grafeas.grafeas_v1.services.grafeas.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/grafeas/v1/docs/grafeas_v1/services_.rst b/owl-bot-staging/grafeas/v1/docs/grafeas_v1/services_.rst new file mode 100644 index 000000000000..ca38222018ff --- /dev/null +++ b/owl-bot-staging/grafeas/v1/docs/grafeas_v1/services_.rst @@ -0,0 +1,6 @@ +Services for Grafeas Grafeas v1 API +=================================== +.. toctree:: + :maxdepth: 2 + + grafeas diff --git a/owl-bot-staging/grafeas/v1/docs/grafeas_v1/types_.rst b/owl-bot-staging/grafeas/v1/docs/grafeas_v1/types_.rst new file mode 100644 index 000000000000..5808795e6eb1 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/docs/grafeas_v1/types_.rst @@ -0,0 +1,6 @@ +Types for Grafeas Grafeas v1 API +================================ + +.. automodule:: grafeas.grafeas_v1.types + :members: + :show-inheritance: diff --git a/owl-bot-staging/grafeas/v1/docs/index.rst b/owl-bot-staging/grafeas/v1/docs/index.rst new file mode 100644 index 000000000000..35750509477c --- /dev/null +++ b/owl-bot-staging/grafeas/v1/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + grafeas_v1/services_ + grafeas_v1/types_ diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas/__init__.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas/__init__.py new file mode 100644 index 000000000000..f2282fa0cc79 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas/__init__.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from grafeas.grafeas import gapic_version as package_version + +__version__ = package_version.__version__ + + +from grafeas.grafeas_v1.services.grafeas.client import GrafeasClient +from grafeas.grafeas_v1.services.grafeas.async_client import GrafeasAsyncClient + +from grafeas.grafeas_v1.types.attestation import AttestationNote +from grafeas.grafeas_v1.types.attestation import AttestationOccurrence +from grafeas.grafeas_v1.types.attestation import Jwt +from grafeas.grafeas_v1.types.build import BuildNote +from grafeas.grafeas_v1.types.build import BuildOccurrence +from grafeas.grafeas_v1.types.common import Digest +from grafeas.grafeas_v1.types.common import Envelope +from grafeas.grafeas_v1.types.common import EnvelopeSignature +from grafeas.grafeas_v1.types.common import FileLocation +from grafeas.grafeas_v1.types.common import License +from grafeas.grafeas_v1.types.common import RelatedUrl +from grafeas.grafeas_v1.types.common import Signature +from grafeas.grafeas_v1.types.common import NoteKind +from grafeas.grafeas_v1.types.compliance import ComplianceNote +from grafeas.grafeas_v1.types.compliance import ComplianceOccurrence +from grafeas.grafeas_v1.types.compliance import ComplianceVersion +from grafeas.grafeas_v1.types.compliance import NonCompliantFile +from grafeas.grafeas_v1.types.cvss import CVSS +from grafeas.grafeas_v1.types.cvss import CVSSv3 +from grafeas.grafeas_v1.types.cvss import CVSSVersion +from grafeas.grafeas_v1.types.deployment import DeploymentNote +from grafeas.grafeas_v1.types.deployment import DeploymentOccurrence +from grafeas.grafeas_v1.types.discovery import DiscoveryNote +from grafeas.grafeas_v1.types.discovery import DiscoveryOccurrence +from grafeas.grafeas_v1.types.dsse_attestation import DSSEAttestationNote +from grafeas.grafeas_v1.types.dsse_attestation import DSSEAttestationOccurrence +from grafeas.grafeas_v1.types.grafeas import BatchCreateNotesRequest +from grafeas.grafeas_v1.types.grafeas import BatchCreateNotesResponse +from grafeas.grafeas_v1.types.grafeas import BatchCreateOccurrencesRequest +from grafeas.grafeas_v1.types.grafeas import BatchCreateOccurrencesResponse +from grafeas.grafeas_v1.types.grafeas import CreateNoteRequest +from grafeas.grafeas_v1.types.grafeas import CreateOccurrenceRequest +from grafeas.grafeas_v1.types.grafeas import DeleteNoteRequest +from grafeas.grafeas_v1.types.grafeas import DeleteOccurrenceRequest +from grafeas.grafeas_v1.types.grafeas import GetNoteRequest +from grafeas.grafeas_v1.types.grafeas import GetOccurrenceNoteRequest +from grafeas.grafeas_v1.types.grafeas import GetOccurrenceRequest +from grafeas.grafeas_v1.types.grafeas import ListNoteOccurrencesRequest +from grafeas.grafeas_v1.types.grafeas import ListNoteOccurrencesResponse +from grafeas.grafeas_v1.types.grafeas import ListNotesRequest +from grafeas.grafeas_v1.types.grafeas import ListNotesResponse +from grafeas.grafeas_v1.types.grafeas import ListOccurrencesRequest +from grafeas.grafeas_v1.types.grafeas import ListOccurrencesResponse +from grafeas.grafeas_v1.types.grafeas import Note +from grafeas.grafeas_v1.types.grafeas import Occurrence +from grafeas.grafeas_v1.types.grafeas import UpdateNoteRequest +from grafeas.grafeas_v1.types.grafeas import UpdateOccurrenceRequest +from grafeas.grafeas_v1.types.image import Fingerprint +from grafeas.grafeas_v1.types.image import ImageNote +from grafeas.grafeas_v1.types.image import ImageOccurrence +from grafeas.grafeas_v1.types.image import Layer +from grafeas.grafeas_v1.types.intoto_provenance import BuilderConfig +from grafeas.grafeas_v1.types.intoto_provenance import Completeness +from grafeas.grafeas_v1.types.intoto_provenance import InTotoProvenance +from grafeas.grafeas_v1.types.intoto_provenance import Metadata +from grafeas.grafeas_v1.types.intoto_provenance import Recipe +from grafeas.grafeas_v1.types.intoto_statement import InTotoSlsaProvenanceV1 +from grafeas.grafeas_v1.types.intoto_statement import InTotoStatement +from grafeas.grafeas_v1.types.intoto_statement import Subject +from grafeas.grafeas_v1.types.package import Distribution +from grafeas.grafeas_v1.types.package import Location +from grafeas.grafeas_v1.types.package import PackageNote +from grafeas.grafeas_v1.types.package import PackageOccurrence +from grafeas.grafeas_v1.types.package import Version +from grafeas.grafeas_v1.types.package import Architecture +from grafeas.grafeas_v1.types.provenance import AliasContext +from grafeas.grafeas_v1.types.provenance import Artifact +from grafeas.grafeas_v1.types.provenance import BuildProvenance +from grafeas.grafeas_v1.types.provenance import CloudRepoSourceContext +from grafeas.grafeas_v1.types.provenance import Command +from grafeas.grafeas_v1.types.provenance import FileHashes +from grafeas.grafeas_v1.types.provenance import GerritSourceContext +from grafeas.grafeas_v1.types.provenance import GitSourceContext +from grafeas.grafeas_v1.types.provenance import Hash +from grafeas.grafeas_v1.types.provenance import ProjectRepoId +from grafeas.grafeas_v1.types.provenance import RepoId +from grafeas.grafeas_v1.types.provenance import Source +from grafeas.grafeas_v1.types.provenance import SourceContext +from grafeas.grafeas_v1.types.sbom import SbomReferenceIntotoPayload +from grafeas.grafeas_v1.types.sbom import SbomReferenceIntotoPredicate +from grafeas.grafeas_v1.types.sbom import SBOMReferenceNote +from grafeas.grafeas_v1.types.sbom import SBOMReferenceOccurrence +from grafeas.grafeas_v1.types.severity import Severity +from grafeas.grafeas_v1.types.slsa_provenance import SlsaProvenance +from grafeas.grafeas_v1.types.slsa_provenance_zero_two import SlsaProvenanceZeroTwo +from grafeas.grafeas_v1.types.upgrade import UpgradeDistribution +from grafeas.grafeas_v1.types.upgrade import UpgradeNote +from grafeas.grafeas_v1.types.upgrade import UpgradeOccurrence +from grafeas.grafeas_v1.types.upgrade import WindowsUpdate +from grafeas.grafeas_v1.types.vex import VulnerabilityAssessmentNote +from grafeas.grafeas_v1.types.vulnerability import VulnerabilityNote +from grafeas.grafeas_v1.types.vulnerability import VulnerabilityOccurrence + +__all__ = ('GrafeasClient', + 'GrafeasAsyncClient', + 'AttestationNote', + 'AttestationOccurrence', + 'Jwt', + 'BuildNote', + 'BuildOccurrence', + 'Digest', + 'Envelope', + 'EnvelopeSignature', + 'FileLocation', + 'License', + 'RelatedUrl', + 'Signature', + 'NoteKind', + 'ComplianceNote', + 'ComplianceOccurrence', + 'ComplianceVersion', + 'NonCompliantFile', + 'CVSS', + 'CVSSv3', + 'CVSSVersion', + 'DeploymentNote', + 'DeploymentOccurrence', + 'DiscoveryNote', + 'DiscoveryOccurrence', + 'DSSEAttestationNote', + 'DSSEAttestationOccurrence', + 'BatchCreateNotesRequest', + 'BatchCreateNotesResponse', + 'BatchCreateOccurrencesRequest', + 'BatchCreateOccurrencesResponse', + 'CreateNoteRequest', + 'CreateOccurrenceRequest', + 'DeleteNoteRequest', + 'DeleteOccurrenceRequest', + 'GetNoteRequest', + 'GetOccurrenceNoteRequest', + 'GetOccurrenceRequest', + 'ListNoteOccurrencesRequest', + 'ListNoteOccurrencesResponse', + 'ListNotesRequest', + 'ListNotesResponse', + 'ListOccurrencesRequest', + 'ListOccurrencesResponse', + 'Note', + 'Occurrence', + 'UpdateNoteRequest', + 'UpdateOccurrenceRequest', + 'Fingerprint', + 'ImageNote', + 'ImageOccurrence', + 'Layer', + 'BuilderConfig', + 'Completeness', + 'InTotoProvenance', + 'Metadata', + 'Recipe', + 'InTotoSlsaProvenanceV1', + 'InTotoStatement', + 'Subject', + 'Distribution', + 'Location', + 'PackageNote', + 'PackageOccurrence', + 'Version', + 'Architecture', + 'AliasContext', + 'Artifact', + 'BuildProvenance', + 'CloudRepoSourceContext', + 'Command', + 'FileHashes', + 'GerritSourceContext', + 'GitSourceContext', + 'Hash', + 'ProjectRepoId', + 'RepoId', + 'Source', + 'SourceContext', + 'SbomReferenceIntotoPayload', + 'SbomReferenceIntotoPredicate', + 'SBOMReferenceNote', + 'SBOMReferenceOccurrence', + 'Severity', + 'SlsaProvenance', + 'SlsaProvenanceZeroTwo', + 'UpgradeDistribution', + 'UpgradeNote', + 'UpgradeOccurrence', + 'WindowsUpdate', + 'VulnerabilityAssessmentNote', + 'VulnerabilityNote', + 'VulnerabilityOccurrence', +) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas/gapic_version.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas/gapic_version.py new file mode 100644 index 000000000000..558c8aab67c5 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/grafeas/v1/grafeas/grafeas/py.typed b/owl-bot-staging/grafeas/v1/grafeas/grafeas/py.typed new file mode 100644 index 000000000000..49e8f71d60b7 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The grafeas package uses inline types. diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/__init__.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/__init__.py new file mode 100644 index 000000000000..7a4f4fa690fd --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/__init__.py @@ -0,0 +1,212 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from grafeas.grafeas_v1 import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.grafeas import GrafeasClient +from .services.grafeas import GrafeasAsyncClient + +from .types.attestation import AttestationNote +from .types.attestation import AttestationOccurrence +from .types.attestation import Jwt +from .types.build import BuildNote +from .types.build import BuildOccurrence +from .types.common import Digest +from .types.common import Envelope +from .types.common import EnvelopeSignature +from .types.common import FileLocation +from .types.common import License +from .types.common import RelatedUrl +from .types.common import Signature +from .types.common import NoteKind +from .types.compliance import ComplianceNote +from .types.compliance import ComplianceOccurrence +from .types.compliance import ComplianceVersion +from .types.compliance import NonCompliantFile +from .types.cvss import CVSS +from .types.cvss import CVSSv3 +from .types.cvss import CVSSVersion +from .types.deployment import DeploymentNote +from .types.deployment import DeploymentOccurrence +from .types.discovery import DiscoveryNote +from .types.discovery import DiscoveryOccurrence +from .types.dsse_attestation import DSSEAttestationNote +from .types.dsse_attestation import DSSEAttestationOccurrence +from .types.grafeas import BatchCreateNotesRequest +from .types.grafeas import BatchCreateNotesResponse +from .types.grafeas import BatchCreateOccurrencesRequest +from .types.grafeas import BatchCreateOccurrencesResponse +from .types.grafeas import CreateNoteRequest +from .types.grafeas import CreateOccurrenceRequest +from .types.grafeas import DeleteNoteRequest +from .types.grafeas import DeleteOccurrenceRequest +from .types.grafeas import GetNoteRequest +from .types.grafeas import GetOccurrenceNoteRequest +from .types.grafeas import GetOccurrenceRequest +from .types.grafeas import ListNoteOccurrencesRequest +from .types.grafeas import ListNoteOccurrencesResponse +from .types.grafeas import ListNotesRequest +from .types.grafeas import ListNotesResponse +from .types.grafeas import ListOccurrencesRequest +from .types.grafeas import ListOccurrencesResponse +from .types.grafeas import Note +from .types.grafeas import Occurrence +from .types.grafeas import UpdateNoteRequest +from .types.grafeas import UpdateOccurrenceRequest +from .types.image import Fingerprint +from .types.image import ImageNote +from .types.image import ImageOccurrence +from .types.image import Layer +from .types.intoto_provenance import BuilderConfig +from .types.intoto_provenance import Completeness +from .types.intoto_provenance import InTotoProvenance +from .types.intoto_provenance import Metadata +from .types.intoto_provenance import Recipe +from .types.intoto_statement import InTotoSlsaProvenanceV1 +from .types.intoto_statement import InTotoStatement +from .types.intoto_statement import Subject +from .types.package import Distribution +from .types.package import Location +from .types.package import PackageNote +from .types.package import PackageOccurrence +from .types.package import Version +from .types.package import Architecture +from .types.provenance import AliasContext +from .types.provenance import Artifact +from .types.provenance import BuildProvenance +from .types.provenance import CloudRepoSourceContext +from .types.provenance import Command +from .types.provenance import FileHashes +from .types.provenance import GerritSourceContext +from .types.provenance import GitSourceContext +from .types.provenance import Hash +from .types.provenance import ProjectRepoId +from .types.provenance import RepoId +from .types.provenance import Source +from .types.provenance import SourceContext +from .types.sbom import SbomReferenceIntotoPayload +from .types.sbom import SbomReferenceIntotoPredicate +from .types.sbom import SBOMReferenceNote +from .types.sbom import SBOMReferenceOccurrence +from .types.severity import Severity +from .types.slsa_provenance import SlsaProvenance +from .types.slsa_provenance_zero_two import SlsaProvenanceZeroTwo +from .types.upgrade import UpgradeDistribution +from .types.upgrade import UpgradeNote +from .types.upgrade import UpgradeOccurrence +from .types.upgrade import WindowsUpdate +from .types.vex import VulnerabilityAssessmentNote +from .types.vulnerability import VulnerabilityNote +from .types.vulnerability import VulnerabilityOccurrence + +__all__ = ( + 'GrafeasAsyncClient', +'AliasContext', +'Architecture', +'Artifact', +'AttestationNote', +'AttestationOccurrence', +'BatchCreateNotesRequest', +'BatchCreateNotesResponse', +'BatchCreateOccurrencesRequest', +'BatchCreateOccurrencesResponse', +'BuildNote', +'BuildOccurrence', +'BuildProvenance', +'BuilderConfig', +'CVSS', +'CVSSVersion', +'CVSSv3', +'CloudRepoSourceContext', +'Command', +'Completeness', +'ComplianceNote', +'ComplianceOccurrence', +'ComplianceVersion', +'CreateNoteRequest', +'CreateOccurrenceRequest', +'DSSEAttestationNote', +'DSSEAttestationOccurrence', +'DeleteNoteRequest', +'DeleteOccurrenceRequest', +'DeploymentNote', +'DeploymentOccurrence', +'Digest', +'DiscoveryNote', +'DiscoveryOccurrence', +'Distribution', +'Envelope', +'EnvelopeSignature', +'FileHashes', +'FileLocation', +'Fingerprint', +'GerritSourceContext', +'GetNoteRequest', +'GetOccurrenceNoteRequest', +'GetOccurrenceRequest', +'GitSourceContext', +'GrafeasClient', +'Hash', +'ImageNote', +'ImageOccurrence', +'InTotoProvenance', +'InTotoSlsaProvenanceV1', +'InTotoStatement', +'Jwt', +'Layer', +'License', +'ListNoteOccurrencesRequest', +'ListNoteOccurrencesResponse', +'ListNotesRequest', +'ListNotesResponse', +'ListOccurrencesRequest', +'ListOccurrencesResponse', +'Location', +'Metadata', +'NonCompliantFile', +'Note', +'NoteKind', +'Occurrence', +'PackageNote', +'PackageOccurrence', +'ProjectRepoId', +'Recipe', +'RelatedUrl', +'RepoId', +'SBOMReferenceNote', +'SBOMReferenceOccurrence', +'SbomReferenceIntotoPayload', +'SbomReferenceIntotoPredicate', +'Severity', +'Signature', +'SlsaProvenance', +'SlsaProvenanceZeroTwo', +'Source', +'SourceContext', +'Subject', +'UpdateNoteRequest', +'UpdateOccurrenceRequest', +'UpgradeDistribution', +'UpgradeNote', +'UpgradeOccurrence', +'Version', +'VulnerabilityAssessmentNote', +'VulnerabilityNote', +'VulnerabilityOccurrence', +'WindowsUpdate', +) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_metadata.json b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_metadata.json new file mode 100644 index 000000000000..ec505dda48a9 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_metadata.json @@ -0,0 +1,238 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "grafeas.grafeas_v1", + "protoPackage": "grafeas.v1", + "schema": "1.0", + "services": { + "Grafeas": { + "clients": { + "grpc": { + "libraryClient": "GrafeasClient", + "rpcs": { + "BatchCreateNotes": { + "methods": [ + "batch_create_notes" + ] + }, + "BatchCreateOccurrences": { + "methods": [ + "batch_create_occurrences" + ] + }, + "CreateNote": { + "methods": [ + "create_note" + ] + }, + "CreateOccurrence": { + "methods": [ + "create_occurrence" + ] + }, + "DeleteNote": { + "methods": [ + "delete_note" + ] + }, + "DeleteOccurrence": { + "methods": [ + "delete_occurrence" + ] + }, + "GetNote": { + "methods": [ + "get_note" + ] + }, + "GetOccurrence": { + "methods": [ + "get_occurrence" + ] + }, + "GetOccurrenceNote": { + "methods": [ + "get_occurrence_note" + ] + }, + "ListNoteOccurrences": { + "methods": [ + "list_note_occurrences" + ] + }, + "ListNotes": { + "methods": [ + "list_notes" + ] + }, + "ListOccurrences": { + "methods": [ + "list_occurrences" + ] + }, + "UpdateNote": { + "methods": [ + "update_note" + ] + }, + "UpdateOccurrence": { + "methods": [ + "update_occurrence" + ] + } + } + }, + "grpc-async": { + "libraryClient": "GrafeasAsyncClient", + "rpcs": { + "BatchCreateNotes": { + "methods": [ + "batch_create_notes" + ] + }, + "BatchCreateOccurrences": { + "methods": [ + "batch_create_occurrences" + ] + }, + "CreateNote": { + "methods": [ + "create_note" + ] + }, + "CreateOccurrence": { + "methods": [ + "create_occurrence" + ] + }, + "DeleteNote": { + "methods": [ + "delete_note" + ] + }, + "DeleteOccurrence": { + "methods": [ + "delete_occurrence" + ] + }, + "GetNote": { + "methods": [ + "get_note" + ] + }, + "GetOccurrence": { + "methods": [ + "get_occurrence" + ] + }, + "GetOccurrenceNote": { + "methods": [ + "get_occurrence_note" + ] + }, + "ListNoteOccurrences": { + "methods": [ + "list_note_occurrences" + ] + }, + "ListNotes": { + "methods": [ + "list_notes" + ] + }, + "ListOccurrences": { + "methods": [ + "list_occurrences" + ] + }, + "UpdateNote": { + "methods": [ + "update_note" + ] + }, + "UpdateOccurrence": { + "methods": [ + "update_occurrence" + ] + } + } + }, + "rest": { + "libraryClient": "GrafeasClient", + "rpcs": { + "BatchCreateNotes": { + "methods": [ + "batch_create_notes" + ] + }, + "BatchCreateOccurrences": { + "methods": [ + "batch_create_occurrences" + ] + }, + "CreateNote": { + "methods": [ + "create_note" + ] + }, + "CreateOccurrence": { + "methods": [ + "create_occurrence" + ] + }, + "DeleteNote": { + "methods": [ + "delete_note" + ] + }, + "DeleteOccurrence": { + "methods": [ + "delete_occurrence" + ] + }, + "GetNote": { + "methods": [ + "get_note" + ] + }, + "GetOccurrence": { + "methods": [ + "get_occurrence" + ] + }, + "GetOccurrenceNote": { + "methods": [ + "get_occurrence_note" + ] + }, + "ListNoteOccurrences": { + "methods": [ + "list_note_occurrences" + ] + }, + "ListNotes": { + "methods": [ + "list_notes" + ] + }, + "ListOccurrences": { + "methods": [ + "list_occurrences" + ] + }, + "UpdateNote": { + "methods": [ + "update_note" + ] + }, + "UpdateOccurrence": { + "methods": [ + "update_occurrence" + ] + } + } + } + } + } + } +} diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_version.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_version.py new file mode 100644 index 000000000000..558c8aab67c5 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/grafeas/v1/grafeas/grafeas_v1/py.typed b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/py.typed new file mode 100644 index 000000000000..49e8f71d60b7 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The grafeas package uses inline types. diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/__init__.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/__init__.py new file mode 100644 index 000000000000..8f6cf068242c --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/grafeas/v1/grafeas/grafeas_v1/services/grafeas/__init__.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/__init__.py new file mode 100644 index 000000000000..b1d682230d78 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 GrafeasClient +from .async_client import GrafeasAsyncClient + +__all__ = ( + 'GrafeasClient', + 'GrafeasAsyncClient', +) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/async_client.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/async_client.py new file mode 100644 index 000000000000..54992211d44a --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/async_client.py @@ -0,0 +1,1836 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 re +from typing import Dict, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from grafeas.grafeas_v1 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + + +try: + OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from grafeas.grafeas_v1.services.grafeas import pagers +from grafeas.grafeas_v1.types import attestation +from grafeas.grafeas_v1.types import build +from grafeas.grafeas_v1.types import common +from grafeas.grafeas_v1.types import compliance +from grafeas.grafeas_v1.types import deployment +from grafeas.grafeas_v1.types import discovery +from grafeas.grafeas_v1.types import dsse_attestation +from grafeas.grafeas_v1.types import grafeas +from grafeas.grafeas_v1.types import image +from grafeas.grafeas_v1.types import package +from grafeas.grafeas_v1.types import sbom +from grafeas.grafeas_v1.types import upgrade +from grafeas.grafeas_v1.types import vex +from grafeas.grafeas_v1.types import vulnerability +from .transports.base import GrafeasTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import GrafeasGrpcAsyncIOTransport +from .client import GrafeasClient + + +class GrafeasAsyncClient: + """`Grafeas `__ API. + + Retrieves analysis results of Cloud components such as Docker + container images. + + Analysis results are stored as a series of occurrences. An + ``Occurrence`` contains information about a specific analysis + instance on a resource. An occurrence refers to a ``Note``. A note + contains details describing the analysis and is generally stored in + a separate project, called a ``Provider``. Multiple occurrences can + refer to the same note. + + For example, an SSL vulnerability could affect multiple images. In + this case, there would be one note for the vulnerability and an + occurrence for each image with the vulnerability referring to that + note. + """ + + _client: GrafeasClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = GrafeasClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = GrafeasClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = GrafeasClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = GrafeasClient._DEFAULT_UNIVERSE + + note_path = staticmethod(GrafeasClient.note_path) + parse_note_path = staticmethod(GrafeasClient.parse_note_path) + occurrence_path = staticmethod(GrafeasClient.occurrence_path) + parse_occurrence_path = staticmethod(GrafeasClient.parse_occurrence_path) + project_path = staticmethod(GrafeasClient.project_path) + parse_project_path = staticmethod(GrafeasClient.parse_project_path) + common_billing_account_path = staticmethod(GrafeasClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(GrafeasClient.parse_common_billing_account_path) + common_folder_path = staticmethod(GrafeasClient.common_folder_path) + parse_common_folder_path = staticmethod(GrafeasClient.parse_common_folder_path) + common_organization_path = staticmethod(GrafeasClient.common_organization_path) + parse_common_organization_path = staticmethod(GrafeasClient.parse_common_organization_path) + common_project_path = staticmethod(GrafeasClient.common_project_path) + parse_common_project_path = staticmethod(GrafeasClient.parse_common_project_path) + common_location_path = staticmethod(GrafeasClient.common_location_path) + parse_common_location_path = staticmethod(GrafeasClient.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: + GrafeasAsyncClient: The constructed client. + """ + return GrafeasClient.from_service_account_info.__func__(GrafeasAsyncClient, 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: + GrafeasAsyncClient: The constructed client. + """ + return GrafeasClient.from_service_account_file.__func__(GrafeasAsyncClient, 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 GrafeasClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> GrafeasTransport: + """Returns the transport used by the client instance. + + Returns: + GrafeasTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = GrafeasClient.get_transport_class + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, GrafeasTransport, Callable[..., GrafeasTransport]]] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the grafeas async 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 (Optional[Union[str,GrafeasTransport,Callable[..., GrafeasTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the GrafeasTransport constructor. + 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. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client = GrafeasClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def get_occurrence(self, + request: Optional[Union[grafeas.GetOccurrenceRequest, 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]] = (), + ) -> grafeas.Occurrence: + r"""Gets the specified occurrence. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + async def sample_get_occurrence(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.GetOccurrenceRequest( + name="name_value", + ) + + # Make the request + response = await client.get_occurrence(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.GetOccurrenceRequest, dict]]): + The request object. Request to get an occurrence. + name (:class:`str`): + The name of the occurrence in the form of + ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.types.Occurrence: + An instance of an analysis type that + has been found on a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.GetOccurrenceRequest): + request = grafeas.GetOccurrenceRequest(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._client._transport._wrapped_methods[self._client._transport.get_occurrence] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_occurrences(self, + request: Optional[Union[grafeas.ListOccurrencesRequest, dict]] = None, + *, + parent: Optional[str] = None, + filter: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListOccurrencesAsyncPager: + r"""Lists occurrences for the specified 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 grafeas import grafeas_v1 + + async def sample_list_occurrences(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.ListOccurrencesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_occurrences(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.ListOccurrencesRequest, dict]]): + The request object. Request to list occurrences. + parent (:class:`str`): + The name of the project to list occurrences for in the + form of ``projects/[PROJECT_ID]``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + filter (:class:`str`): + The filter expression. + This corresponds to the ``filter`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesAsyncPager: + Response for listing occurrences. + + 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, filter]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.ListOccurrencesRequest): + request = grafeas.ListOccurrencesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if filter is not None: + request.filter = filter + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[self._client._transport.list_occurrences] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListOccurrencesAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_occurrence(self, + request: Optional[Union[grafeas.DeleteOccurrenceRequest, 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 the specified occurrence. For example, use + this method to delete an occurrence when the occurrence + is no longer applicable for the given resource. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + async def sample_delete_occurrence(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.DeleteOccurrenceRequest( + name="name_value", + ) + + # Make the request + await client.delete_occurrence(request=request) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.DeleteOccurrenceRequest, dict]]): + The request object. Request to delete an occurrence. + name (:class:`str`): + The name of the occurrence in the form of + ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_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_async.AsyncRetry): Designation of what errors, if any, + should be 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.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.DeleteOccurrenceRequest): + request = grafeas.DeleteOccurrenceRequest(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._client._transport._wrapped_methods[self._client._transport.delete_occurrence] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def create_occurrence(self, + request: Optional[Union[grafeas.CreateOccurrenceRequest, dict]] = None, + *, + parent: Optional[str] = None, + occurrence: Optional[grafeas.Occurrence] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> grafeas.Occurrence: + r"""Creates a new occurrence. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + async def sample_create_occurrence(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.CreateOccurrenceRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_occurrence(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.CreateOccurrenceRequest, dict]]): + The request object. Request to create a new occurrence. + parent (:class:`str`): + The name of the project in the form of + ``projects/[PROJECT_ID]``, under which the occurrence is + to be created. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + occurrence (:class:`grafeas.grafeas_v1.types.Occurrence`): + The occurrence to create. + This corresponds to the ``occurrence`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.types.Occurrence: + An instance of an analysis type that + has been found on a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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, occurrence]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.CreateOccurrenceRequest): + request = grafeas.CreateOccurrenceRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if occurrence is not None: + request.occurrence = occurrence + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[self._client._transport.create_occurrence] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def batch_create_occurrences(self, + request: Optional[Union[grafeas.BatchCreateOccurrencesRequest, dict]] = None, + *, + parent: Optional[str] = None, + occurrences: Optional[MutableSequence[grafeas.Occurrence]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> grafeas.BatchCreateOccurrencesResponse: + r"""Creates new occurrences in batch. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + async def sample_batch_create_occurrences(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.BatchCreateOccurrencesRequest( + parent="parent_value", + ) + + # Make the request + response = await client.batch_create_occurrences(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.BatchCreateOccurrencesRequest, dict]]): + The request object. Request to create occurrences in + batch. + parent (:class:`str`): + The name of the project in the form of + ``projects/[PROJECT_ID]``, under which the occurrences + are to be created. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + occurrences (:class:`MutableSequence[grafeas.grafeas_v1.types.Occurrence]`): + The occurrences to create. Max + allowed length is 1000. + + This corresponds to the ``occurrences`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse: + Response for creating occurrences in + batch. + + """ + # Create or coerce a protobuf request object. + # - Quick 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, occurrences]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.BatchCreateOccurrencesRequest): + request = grafeas.BatchCreateOccurrencesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if occurrences: + request.occurrences.extend(occurrences) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[self._client._transport.batch_create_occurrences] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_occurrence(self, + request: Optional[Union[grafeas.UpdateOccurrenceRequest, dict]] = None, + *, + name: Optional[str] = None, + occurrence: Optional[grafeas.Occurrence] = 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]] = (), + ) -> grafeas.Occurrence: + r"""Updates the specified occurrence. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + async def sample_update_occurrence(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.UpdateOccurrenceRequest( + name="name_value", + ) + + # Make the request + response = await client.update_occurrence(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.UpdateOccurrenceRequest, dict]]): + The request object. Request to update an occurrence. + name (:class:`str`): + The name of the occurrence in the form of + ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + occurrence (:class:`grafeas.grafeas_v1.types.Occurrence`): + The updated occurrence. + This corresponds to the ``occurrence`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The fields to 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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.types.Occurrence: + An instance of an analysis type that + has been found on a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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, occurrence, 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.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.UpdateOccurrenceRequest): + request = grafeas.UpdateOccurrenceRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if occurrence is not None: + request.occurrence = occurrence + 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._client._transport._wrapped_methods[self._client._transport.update_occurrence] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_occurrence_note(self, + request: Optional[Union[grafeas.GetOccurrenceNoteRequest, 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]] = (), + ) -> grafeas.Note: + r"""Gets the note attached to the specified occurrence. + Consumer projects can use this method to get a note that + belongs to a provider 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 grafeas import grafeas_v1 + + async def sample_get_occurrence_note(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.GetOccurrenceNoteRequest( + name="name_value", + ) + + # Make the request + response = await client.get_occurrence_note(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.GetOccurrenceNoteRequest, dict]]): + The request object. Request to get the note to which the + specified occurrence is attached. + name (:class:`str`): + The name of the occurrence in the form of + ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.types.Note: + A type of analysis that can be done + for a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.GetOccurrenceNoteRequest): + request = grafeas.GetOccurrenceNoteRequest(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._client._transport._wrapped_methods[self._client._transport.get_occurrence_note] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_note(self, + request: Optional[Union[grafeas.GetNoteRequest, 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]] = (), + ) -> grafeas.Note: + r"""Gets the specified note. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + async def sample_get_note(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.GetNoteRequest( + name="name_value", + ) + + # Make the request + response = await client.get_note(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.GetNoteRequest, dict]]): + The request object. Request to get a note. + name (:class:`str`): + The name of the note in the form of + ``projects/[PROVIDER_ID]/notes/[NOTE_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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.types.Note: + A type of analysis that can be done + for a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.GetNoteRequest): + request = grafeas.GetNoteRequest(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._client._transport._wrapped_methods[self._client._transport.get_note] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_notes(self, + request: Optional[Union[grafeas.ListNotesRequest, dict]] = None, + *, + parent: Optional[str] = None, + filter: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListNotesAsyncPager: + r"""Lists notes for the specified 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 grafeas import grafeas_v1 + + async def sample_list_notes(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.ListNotesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_notes(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.ListNotesRequest, dict]]): + The request object. Request to list notes. + parent (:class:`str`): + The name of the project to list notes for in the form of + ``projects/[PROJECT_ID]``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + filter (:class:`str`): + The filter expression. + This corresponds to the ``filter`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.services.grafeas.pagers.ListNotesAsyncPager: + Response for listing notes. + + 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, filter]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.ListNotesRequest): + request = grafeas.ListNotesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if filter is not None: + request.filter = filter + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[self._client._transport.list_notes] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListNotesAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_note(self, + request: Optional[Union[grafeas.DeleteNoteRequest, 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 the specified note. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + async def sample_delete_note(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.DeleteNoteRequest( + name="name_value", + ) + + # Make the request + await client.delete_note(request=request) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.DeleteNoteRequest, dict]]): + The request object. Request to delete a note. + name (:class:`str`): + The name of the note in the form of + ``projects/[PROVIDER_ID]/notes/[NOTE_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_async.AsyncRetry): Designation of what errors, if any, + should be 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.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.DeleteNoteRequest): + request = grafeas.DeleteNoteRequest(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._client._transport._wrapped_methods[self._client._transport.delete_note] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def create_note(self, + request: Optional[Union[grafeas.CreateNoteRequest, dict]] = None, + *, + parent: Optional[str] = None, + note_id: Optional[str] = None, + note: Optional[grafeas.Note] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> grafeas.Note: + r"""Creates a new note. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + async def sample_create_note(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.CreateNoteRequest( + parent="parent_value", + note_id="note_id_value", + ) + + # Make the request + response = await client.create_note(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.CreateNoteRequest, dict]]): + The request object. Request to create a new note. + parent (:class:`str`): + The name of the project in the form of + ``projects/[PROJECT_ID]``, under which the note is to be + created. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + note_id (:class:`str`): + The ID to use for this note. + This corresponds to the ``note_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + note (:class:`grafeas.grafeas_v1.types.Note`): + The note to create. + This corresponds to the ``note`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.types.Note: + A type of analysis that can be done + for a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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, note_id, note]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.CreateNoteRequest): + request = grafeas.CreateNoteRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if note_id is not None: + request.note_id = note_id + if note is not None: + request.note = note + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[self._client._transport.create_note] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def batch_create_notes(self, + request: Optional[Union[grafeas.BatchCreateNotesRequest, dict]] = None, + *, + parent: Optional[str] = None, + notes: Optional[MutableMapping[str, grafeas.Note]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> grafeas.BatchCreateNotesResponse: + r"""Creates new notes in batch. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + async def sample_batch_create_notes(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.BatchCreateNotesRequest( + parent="parent_value", + ) + + # Make the request + response = await client.batch_create_notes(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.BatchCreateNotesRequest, dict]]): + The request object. Request to create notes in batch. + parent (:class:`str`): + The name of the project in the form of + ``projects/[PROJECT_ID]``, under which the notes are to + be created. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + notes (:class:`MutableMapping[str, grafeas.grafeas_v1.types.Note]`): + The notes to create. Max allowed + length is 1000. + + This corresponds to the ``notes`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.types.BatchCreateNotesResponse: + Response for creating notes in batch. + """ + # Create or coerce a protobuf request object. + # - Quick 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, notes]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.BatchCreateNotesRequest): + request = grafeas.BatchCreateNotesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + if notes: + request.notes.update(notes) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[self._client._transport.batch_create_notes] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_note(self, + request: Optional[Union[grafeas.UpdateNoteRequest, dict]] = None, + *, + name: Optional[str] = None, + note: Optional[grafeas.Note] = 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]] = (), + ) -> grafeas.Note: + r"""Updates the specified note. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + async def sample_update_note(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.UpdateNoteRequest( + name="name_value", + ) + + # Make the request + response = await client.update_note(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.UpdateNoteRequest, dict]]): + The request object. Request to update a note. + name (:class:`str`): + The name of the note in the form of + ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + note (:class:`grafeas.grafeas_v1.types.Note`): + The updated note. + This corresponds to the ``note`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The fields to 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_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.types.Note: + A type of analysis that can be done + for a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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, note, 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.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.UpdateNoteRequest): + request = grafeas.UpdateNoteRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if note is not None: + request.note = note + 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._client._transport._wrapped_methods[self._client._transport.update_note] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_note_occurrences(self, + request: Optional[Union[grafeas.ListNoteOccurrencesRequest, dict]] = None, + *, + name: Optional[str] = None, + filter: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListNoteOccurrencesAsyncPager: + r"""Lists occurrences referencing the specified note. + Provider projects can use this method to get all + occurrences across consumer projects referencing the + specified note. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + async def sample_list_note_occurrences(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.ListNoteOccurrencesRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_note_occurrences(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[grafeas.grafeas_v1.types.ListNoteOccurrencesRequest, dict]]): + The request object. Request to list occurrences for a + note. + name (:class:`str`): + The name of the note to list occurrences for in the form + of ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + filter (:class:`str`): + The filter expression. + This corresponds to the ``filter`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesAsyncPager: + Response for listing occurrences for + a note. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, filter]) + if request is not None and has_flattened_params: + raise ValueError("If the `request` argument is set, then none of " + "the individual field arguments should be set.") + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.ListNoteOccurrencesRequest): + request = grafeas.ListNoteOccurrencesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if filter is not None: + request.filter = filter + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[self._client._transport.list_note_occurrences] + + # 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), + )), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # 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.ListNoteOccurrencesAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "GrafeasAsyncClient": + 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__ = ( + "GrafeasAsyncClient", +) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/client.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/client.py new file mode 100644 index 000000000000..ddafe8a8b439 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/client.py @@ -0,0 +1,2196 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from grafeas.grafeas_v1 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from grafeas.grafeas_v1.services.grafeas import pagers +from grafeas.grafeas_v1.types import attestation +from grafeas.grafeas_v1.types import build +from grafeas.grafeas_v1.types import common +from grafeas.grafeas_v1.types import compliance +from grafeas.grafeas_v1.types import deployment +from grafeas.grafeas_v1.types import discovery +from grafeas.grafeas_v1.types import dsse_attestation +from grafeas.grafeas_v1.types import grafeas +from grafeas.grafeas_v1.types import image +from grafeas.grafeas_v1.types import package +from grafeas.grafeas_v1.types import sbom +from grafeas.grafeas_v1.types import upgrade +from grafeas.grafeas_v1.types import vex +from grafeas.grafeas_v1.types import vulnerability +from .transports.base import GrafeasTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import GrafeasGrpcTransport +from .transports.grpc_asyncio import GrafeasGrpcAsyncIOTransport +from .transports.rest import GrafeasRestTransport + + +class GrafeasClientMeta(type): + """Metaclass for the Grafeas 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[GrafeasTransport]] + _transport_registry["grpc"] = GrafeasGrpcTransport + _transport_registry["grpc_asyncio"] = GrafeasGrpcAsyncIOTransport + _transport_registry["rest"] = GrafeasRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[GrafeasTransport]: + """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 GrafeasClient(metaclass=GrafeasClientMeta): + """`Grafeas `__ API. + + Retrieves analysis results of Cloud components such as Docker + container images. + + Analysis results are stored as a series of occurrences. An + ``Occurrence`` contains information about a specific analysis + instance on a resource. An occurrence refers to a ``Note``. A note + contains details describing the analysis and is generally stored in + a separate project, called a ``Provider``. Multiple occurrences can + refer to the same note. + + For example, an SSL vulnerability could affect multiple images. In + this case, there would be one note for the vulnerability and an + occurrence for each image with the vulnerability referring to that + note. + """ + + @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") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "containeranalysis.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "containeranalysis.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @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: + GrafeasClient: 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: + GrafeasClient: 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) -> GrafeasTransport: + """Returns the transport used by the client instance. + + Returns: + GrafeasTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def note_path(project: str,note: str,) -> str: + """Returns a fully-qualified note string.""" + return "projects/{project}/notes/{note}".format(project=project, note=note, ) + + @staticmethod + def parse_note_path(path: str) -> Dict[str,str]: + """Parses a note path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/notes/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def occurrence_path(project: str,occurrence: str,) -> str: + """Returns a fully-qualified occurrence string.""" + return "projects/{project}/occurrences/{occurrence}".format(project=project, occurrence=occurrence, ) + + @staticmethod + def parse_occurrence_path(path: str) -> Dict[str,str]: + """Parses a occurrence path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/occurrences/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def project_path(project: str,) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format(project=project, ) + + @staticmethod + def parse_project_path(path: str) -> Dict[str,str]: + """Parses a project path into its component segments.""" + m = re.match(r"^projects/(?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): + """Deprecated. 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. + """ + + warnings.warn("get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning) + 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 + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false").lower() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + 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`") + return use_client_cert == "true", use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint(api_override, client_cert_source, universe_domain, use_mtls_endpoint): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): + _default_universe = GrafeasClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError(f"mTLS is not supported in any universe other than {_default_universe}.") + api_endpoint = GrafeasClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = GrafeasClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=universe_domain) + return api_endpoint + + @staticmethod + def _get_universe_domain(client_universe_domain: Optional[str], universe_domain_env: Optional[str]) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = GrafeasClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + @staticmethod + def _compare_universes(client_universe: str, + credentials: ga_credentials.Credentials) -> bool: + """Returns True iff the universe domains used by the client and credentials match. + + Args: + client_universe (str): The universe domain configured via the client options. + credentials (ga_credentials.Credentials): The credentials being used in the client. + + Returns: + bool: True iff client_universe matches the universe in credentials. + + Raises: + ValueError: when client_universe does not match the universe in credentials. + """ + + default_universe = GrafeasClient._DEFAULT_UNIVERSE + credentials_universe = getattr(credentials, "universe_domain", default_universe) + + if client_universe != credentials_universe: + raise ValueError("The configured universe domain " + f"({client_universe}) does not match the universe domain " + f"found in the credentials ({credentials_universe}). " + "If you haven't configured the universe domain explicitly, " + f"`{default_universe}` is the default.") + return True + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + self._is_universe_domain_valid = (self._is_universe_domain_valid or + GrafeasClient._compare_universes(self.universe_domain, self.transport._credentials)) + return self._is_universe_domain_valid + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[Union[str, GrafeasTransport, Callable[..., GrafeasTransport]]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the grafeas 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 (Optional[Union[str,GrafeasTransport,Callable[..., GrafeasTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the GrafeasTransport constructor. + 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. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "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). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS 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. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + 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. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict(self._client_options) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast(client_options_lib.ClientOptions, self._client_options) + + universe_domain_opt = getattr(self._client_options, 'universe_domain', None) + + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = GrafeasClient._read_environment_variables() + self._client_cert_source = GrafeasClient._get_client_cert_source(self._client_options.client_cert_source, self._use_client_cert) + self._universe_domain = GrafeasClient._get_universe_domain(universe_domain_opt, self._universe_domain_env) + self._api_endpoint = None # updated below, depending on `transport` + + # Initialize the universe domain validation. + self._is_universe_domain_valid = False + + api_key_value = getattr(self._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. + transport_provided = isinstance(transport, GrafeasTransport) + if transport_provided: + # transport is a GrafeasTransport instance. + if credentials or self._client_options.credentials_file or api_key_value: + raise ValueError("When providing a transport instance, " + "provide its credentials directly.") + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(GrafeasTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = (self._api_endpoint or + GrafeasClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint)) + + if not transport_provided: + 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_init: Union[Type[GrafeasTransport], Callable[..., GrafeasTransport]] = ( + GrafeasClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., GrafeasTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + ) + + def get_occurrence(self, + request: Optional[Union[grafeas.GetOccurrenceRequest, 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]] = (), + ) -> grafeas.Occurrence: + r"""Gets the specified occurrence. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + def sample_get_occurrence(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.GetOccurrenceRequest( + name="name_value", + ) + + # Make the request + response = client.get_occurrence(request=request) + + # Handle the response + print(response) + + Args: + request (Union[grafeas.grafeas_v1.types.GetOccurrenceRequest, dict]): + The request object. Request to get an occurrence. + name (str): + The name of the occurrence in the form of + ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_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: + grafeas.grafeas_v1.types.Occurrence: + An instance of an analysis type that + has been found on a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.GetOccurrenceRequest): + request = grafeas.GetOccurrenceRequest(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_occurrence] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_occurrences(self, + request: Optional[Union[grafeas.ListOccurrencesRequest, dict]] = None, + *, + parent: Optional[str] = None, + filter: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListOccurrencesPager: + r"""Lists occurrences for the specified 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 grafeas import grafeas_v1 + + def sample_list_occurrences(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.ListOccurrencesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_occurrences(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[grafeas.grafeas_v1.types.ListOccurrencesRequest, dict]): + The request object. Request to list occurrences. + parent (str): + The name of the project to list occurrences for in the + form of ``projects/[PROJECT_ID]``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + filter (str): + The filter expression. + This corresponds to the ``filter`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesPager: + Response for listing occurrences. + + 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, filter]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.ListOccurrencesRequest): + request = grafeas.ListOccurrencesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if filter is not None: + request.filter = filter + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_occurrences] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListOccurrencesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_occurrence(self, + request: Optional[Union[grafeas.DeleteOccurrenceRequest, 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 the specified occurrence. For example, use + this method to delete an occurrence when the occurrence + is no longer applicable for the given resource. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + def sample_delete_occurrence(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.DeleteOccurrenceRequest( + name="name_value", + ) + + # Make the request + client.delete_occurrence(request=request) + + Args: + request (Union[grafeas.grafeas_v1.types.DeleteOccurrenceRequest, dict]): + The request object. Request to delete an occurrence. + name (str): + The name of the occurrence in the form of + ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_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.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.DeleteOccurrenceRequest): + request = grafeas.DeleteOccurrenceRequest(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_occurrence] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def create_occurrence(self, + request: Optional[Union[grafeas.CreateOccurrenceRequest, dict]] = None, + *, + parent: Optional[str] = None, + occurrence: Optional[grafeas.Occurrence] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> grafeas.Occurrence: + r"""Creates a new occurrence. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + def sample_create_occurrence(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.CreateOccurrenceRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_occurrence(request=request) + + # Handle the response + print(response) + + Args: + request (Union[grafeas.grafeas_v1.types.CreateOccurrenceRequest, dict]): + The request object. Request to create a new occurrence. + parent (str): + The name of the project in the form of + ``projects/[PROJECT_ID]``, under which the occurrence is + to be created. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + occurrence (grafeas.grafeas_v1.types.Occurrence): + The occurrence to create. + This corresponds to the ``occurrence`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.types.Occurrence: + An instance of an analysis type that + has been found on a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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, occurrence]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.CreateOccurrenceRequest): + request = grafeas.CreateOccurrenceRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if occurrence is not None: + request.occurrence = occurrence + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_occurrence] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_create_occurrences(self, + request: Optional[Union[grafeas.BatchCreateOccurrencesRequest, dict]] = None, + *, + parent: Optional[str] = None, + occurrences: Optional[MutableSequence[grafeas.Occurrence]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> grafeas.BatchCreateOccurrencesResponse: + r"""Creates new occurrences in batch. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + def sample_batch_create_occurrences(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.BatchCreateOccurrencesRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_create_occurrences(request=request) + + # Handle the response + print(response) + + Args: + request (Union[grafeas.grafeas_v1.types.BatchCreateOccurrencesRequest, dict]): + The request object. Request to create occurrences in + batch. + parent (str): + The name of the project in the form of + ``projects/[PROJECT_ID]``, under which the occurrences + are to be created. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + occurrences (MutableSequence[grafeas.grafeas_v1.types.Occurrence]): + The occurrences to create. Max + allowed length is 1000. + + This corresponds to the ``occurrences`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse: + Response for creating occurrences in + batch. + + """ + # Create or coerce a protobuf request object. + # - Quick 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, occurrences]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.BatchCreateOccurrencesRequest): + request = grafeas.BatchCreateOccurrencesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if occurrences is not None: + request.occurrences = occurrences + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_create_occurrences] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_occurrence(self, + request: Optional[Union[grafeas.UpdateOccurrenceRequest, dict]] = None, + *, + name: Optional[str] = None, + occurrence: Optional[grafeas.Occurrence] = 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]] = (), + ) -> grafeas.Occurrence: + r"""Updates the specified occurrence. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + def sample_update_occurrence(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.UpdateOccurrenceRequest( + name="name_value", + ) + + # Make the request + response = client.update_occurrence(request=request) + + # Handle the response + print(response) + + Args: + request (Union[grafeas.grafeas_v1.types.UpdateOccurrenceRequest, dict]): + The request object. Request to update an occurrence. + name (str): + The name of the occurrence in the form of + ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + occurrence (grafeas.grafeas_v1.types.Occurrence): + The updated occurrence. + This corresponds to the ``occurrence`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The fields to 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: + grafeas.grafeas_v1.types.Occurrence: + An instance of an analysis type that + has been found on a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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, occurrence, 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.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.UpdateOccurrenceRequest): + request = grafeas.UpdateOccurrenceRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if occurrence is not None: + request.occurrence = occurrence + 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_occurrence] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_occurrence_note(self, + request: Optional[Union[grafeas.GetOccurrenceNoteRequest, 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]] = (), + ) -> grafeas.Note: + r"""Gets the note attached to the specified occurrence. + Consumer projects can use this method to get a note that + belongs to a provider 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 grafeas import grafeas_v1 + + def sample_get_occurrence_note(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.GetOccurrenceNoteRequest( + name="name_value", + ) + + # Make the request + response = client.get_occurrence_note(request=request) + + # Handle the response + print(response) + + Args: + request (Union[grafeas.grafeas_v1.types.GetOccurrenceNoteRequest, dict]): + The request object. Request to get the note to which the + specified occurrence is attached. + name (str): + The name of the occurrence in the form of + ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_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: + grafeas.grafeas_v1.types.Note: + A type of analysis that can be done + for a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.GetOccurrenceNoteRequest): + request = grafeas.GetOccurrenceNoteRequest(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_occurrence_note] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_note(self, + request: Optional[Union[grafeas.GetNoteRequest, 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]] = (), + ) -> grafeas.Note: + r"""Gets the specified note. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + def sample_get_note(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.GetNoteRequest( + name="name_value", + ) + + # Make the request + response = client.get_note(request=request) + + # Handle the response + print(response) + + Args: + request (Union[grafeas.grafeas_v1.types.GetNoteRequest, dict]): + The request object. Request to get a note. + name (str): + The name of the note in the form of + ``projects/[PROVIDER_ID]/notes/[NOTE_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: + grafeas.grafeas_v1.types.Note: + A type of analysis that can be done + for a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.GetNoteRequest): + request = grafeas.GetNoteRequest(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_note] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_notes(self, + request: Optional[Union[grafeas.ListNotesRequest, dict]] = None, + *, + parent: Optional[str] = None, + filter: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListNotesPager: + r"""Lists notes for the specified 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 grafeas import grafeas_v1 + + def sample_list_notes(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.ListNotesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_notes(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[grafeas.grafeas_v1.types.ListNotesRequest, dict]): + The request object. Request to list notes. + parent (str): + The name of the project to list notes for in the form of + ``projects/[PROJECT_ID]``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + filter (str): + The filter expression. + This corresponds to the ``filter`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.services.grafeas.pagers.ListNotesPager: + Response for listing notes. + + 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, filter]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.ListNotesRequest): + request = grafeas.ListNotesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if filter is not None: + request.filter = filter + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_notes] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListNotesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_note(self, + request: Optional[Union[grafeas.DeleteNoteRequest, 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 the specified note. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + def sample_delete_note(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.DeleteNoteRequest( + name="name_value", + ) + + # Make the request + client.delete_note(request=request) + + Args: + request (Union[grafeas.grafeas_v1.types.DeleteNoteRequest, dict]): + The request object. Request to delete a note. + name (str): + The name of the note in the form of + ``projects/[PROVIDER_ID]/notes/[NOTE_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.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.DeleteNoteRequest): + request = grafeas.DeleteNoteRequest(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_note] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def create_note(self, + request: Optional[Union[grafeas.CreateNoteRequest, dict]] = None, + *, + parent: Optional[str] = None, + note_id: Optional[str] = None, + note: Optional[grafeas.Note] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> grafeas.Note: + r"""Creates a new note. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + def sample_create_note(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.CreateNoteRequest( + parent="parent_value", + note_id="note_id_value", + ) + + # Make the request + response = client.create_note(request=request) + + # Handle the response + print(response) + + Args: + request (Union[grafeas.grafeas_v1.types.CreateNoteRequest, dict]): + The request object. Request to create a new note. + parent (str): + The name of the project in the form of + ``projects/[PROJECT_ID]``, under which the note is to be + created. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + note_id (str): + The ID to use for this note. + This corresponds to the ``note_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + note (grafeas.grafeas_v1.types.Note): + The note to create. + This corresponds to the ``note`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.types.Note: + A type of analysis that can be done + for a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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, note_id, note]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.CreateNoteRequest): + request = grafeas.CreateNoteRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if note_id is not None: + request.note_id = note_id + if note is not None: + request.note = note + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_note] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_create_notes(self, + request: Optional[Union[grafeas.BatchCreateNotesRequest, dict]] = None, + *, + parent: Optional[str] = None, + notes: Optional[MutableMapping[str, grafeas.Note]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> grafeas.BatchCreateNotesResponse: + r"""Creates new notes in batch. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + def sample_batch_create_notes(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.BatchCreateNotesRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_create_notes(request=request) + + # Handle the response + print(response) + + Args: + request (Union[grafeas.grafeas_v1.types.BatchCreateNotesRequest, dict]): + The request object. Request to create notes in batch. + parent (str): + The name of the project in the form of + ``projects/[PROJECT_ID]``, under which the notes are to + be created. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + notes (MutableMapping[str, grafeas.grafeas_v1.types.Note]): + The notes to create. Max allowed + length is 1000. + + This corresponds to the ``notes`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.types.BatchCreateNotesResponse: + Response for creating notes in batch. + """ + # Create or coerce a protobuf request object. + # - Quick 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, notes]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.BatchCreateNotesRequest): + request = grafeas.BatchCreateNotesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if notes is not None: + request.notes = notes + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_create_notes] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_note(self, + request: Optional[Union[grafeas.UpdateNoteRequest, dict]] = None, + *, + name: Optional[str] = None, + note: Optional[grafeas.Note] = 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]] = (), + ) -> grafeas.Note: + r"""Updates the specified note. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + def sample_update_note(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.UpdateNoteRequest( + name="name_value", + ) + + # Make the request + response = client.update_note(request=request) + + # Handle the response + print(response) + + Args: + request (Union[grafeas.grafeas_v1.types.UpdateNoteRequest, dict]): + The request object. Request to update a note. + name (str): + The name of the note in the form of + ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + note (grafeas.grafeas_v1.types.Note): + The updated note. + This corresponds to the ``note`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The fields to 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: + grafeas.grafeas_v1.types.Note: + A type of analysis that can be done + for a resource. + + """ + # Create or coerce a protobuf request object. + # - Quick 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, note, 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.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.UpdateNoteRequest): + request = grafeas.UpdateNoteRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if note is not None: + request.note = note + 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_note] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_note_occurrences(self, + request: Optional[Union[grafeas.ListNoteOccurrencesRequest, dict]] = None, + *, + name: Optional[str] = None, + filter: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListNoteOccurrencesPager: + r"""Lists occurrences referencing the specified note. + Provider projects can use this method to get all + occurrences across consumer projects referencing the + specified note. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from grafeas import grafeas_v1 + + def sample_list_note_occurrences(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.ListNoteOccurrencesRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_note_occurrences(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[grafeas.grafeas_v1.types.ListNoteOccurrencesRequest, dict]): + The request object. Request to list occurrences for a + note. + name (str): + The name of the note to list occurrences for in the form + of ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + filter (str): + The filter expression. + This corresponds to the ``filter`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesPager: + Response for listing occurrences for + a note. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name, filter]) + if request is not None and has_flattened_params: + raise ValueError('If the `request` argument is set, then none of ' + 'the individual field arguments should be set.') + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, grafeas.ListNoteOccurrencesRequest): + request = grafeas.ListNoteOccurrencesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + if filter is not None: + request.filter = filter + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_note_occurrences] + + # 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), + )), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # 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.ListNoteOccurrencesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "GrafeasClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "GrafeasClient", +) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/pagers.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/pagers.py new file mode 100644 index 000000000000..b905bf6d42fb --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/pagers.py @@ -0,0 +1,432 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async +from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator, Union +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from grafeas.grafeas_v1.types import grafeas + + +class ListOccurrencesPager: + """A pager for iterating through ``list_occurrences`` requests. + + This class thinly wraps an initial + :class:`grafeas.grafeas_v1.types.ListOccurrencesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``occurrences`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListOccurrences`` requests and continue to iterate + through the ``occurrences`` field on the + corresponding responses. + + All the usual :class:`grafeas.grafeas_v1.types.ListOccurrencesResponse` + 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[..., grafeas.ListOccurrencesResponse], + request: grafeas.ListOccurrencesRequest, + response: grafeas.ListOccurrencesResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (grafeas.grafeas_v1.types.ListOccurrencesRequest): + The initial request object. + response (grafeas.grafeas_v1.types.ListOccurrencesResponse): + The initial response object. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = grafeas.ListOccurrencesRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[grafeas.ListOccurrencesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, retry=self._retry, timeout=self._timeout, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[grafeas.Occurrence]: + for page in self.pages: + yield from page.occurrences + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListOccurrencesAsyncPager: + """A pager for iterating through ``list_occurrences`` requests. + + This class thinly wraps an initial + :class:`grafeas.grafeas_v1.types.ListOccurrencesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``occurrences`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListOccurrences`` requests and continue to iterate + through the ``occurrences`` field on the + corresponding responses. + + All the usual :class:`grafeas.grafeas_v1.types.ListOccurrencesResponse` + 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[grafeas.ListOccurrencesResponse]], + request: grafeas.ListOccurrencesRequest, + response: grafeas.ListOccurrencesResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (grafeas.grafeas_v1.types.ListOccurrencesRequest): + The initial request object. + response (grafeas.grafeas_v1.types.ListOccurrencesResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = grafeas.ListOccurrencesRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[grafeas.ListOccurrencesResponse]: + 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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[grafeas.Occurrence]: + async def async_generator(): + async for page in self.pages: + for response in page.occurrences: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListNotesPager: + """A pager for iterating through ``list_notes`` requests. + + This class thinly wraps an initial + :class:`grafeas.grafeas_v1.types.ListNotesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``notes`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListNotes`` requests and continue to iterate + through the ``notes`` field on the + corresponding responses. + + All the usual :class:`grafeas.grafeas_v1.types.ListNotesResponse` + 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[..., grafeas.ListNotesResponse], + request: grafeas.ListNotesRequest, + response: grafeas.ListNotesResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (grafeas.grafeas_v1.types.ListNotesRequest): + The initial request object. + response (grafeas.grafeas_v1.types.ListNotesResponse): + The initial response object. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = grafeas.ListNotesRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[grafeas.ListNotesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, retry=self._retry, timeout=self._timeout, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[grafeas.Note]: + for page in self.pages: + yield from page.notes + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListNotesAsyncPager: + """A pager for iterating through ``list_notes`` requests. + + This class thinly wraps an initial + :class:`grafeas.grafeas_v1.types.ListNotesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``notes`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListNotes`` requests and continue to iterate + through the ``notes`` field on the + corresponding responses. + + All the usual :class:`grafeas.grafeas_v1.types.ListNotesResponse` + 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[grafeas.ListNotesResponse]], + request: grafeas.ListNotesRequest, + response: grafeas.ListNotesResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (grafeas.grafeas_v1.types.ListNotesRequest): + The initial request object. + response (grafeas.grafeas_v1.types.ListNotesResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = grafeas.ListNotesRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[grafeas.ListNotesResponse]: + 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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[grafeas.Note]: + async def async_generator(): + async for page in self.pages: + for response in page.notes: + yield response + + return async_generator() + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListNoteOccurrencesPager: + """A pager for iterating through ``list_note_occurrences`` requests. + + This class thinly wraps an initial + :class:`grafeas.grafeas_v1.types.ListNoteOccurrencesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``occurrences`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListNoteOccurrences`` requests and continue to iterate + through the ``occurrences`` field on the + corresponding responses. + + All the usual :class:`grafeas.grafeas_v1.types.ListNoteOccurrencesResponse` + 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[..., grafeas.ListNoteOccurrencesResponse], + request: grafeas.ListNoteOccurrencesRequest, + response: grafeas.ListNoteOccurrencesResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (grafeas.grafeas_v1.types.ListNoteOccurrencesRequest): + The initial request object. + response (grafeas.grafeas_v1.types.ListNoteOccurrencesResponse): + The initial response object. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = grafeas.ListNoteOccurrencesRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[grafeas.ListNoteOccurrencesResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method(self._request, retry=self._retry, timeout=self._timeout, metadata=self._metadata) + yield self._response + + def __iter__(self) -> Iterator[grafeas.Occurrence]: + for page in self.pages: + yield from page.occurrences + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListNoteOccurrencesAsyncPager: + """A pager for iterating through ``list_note_occurrences`` requests. + + This class thinly wraps an initial + :class:`grafeas.grafeas_v1.types.ListNoteOccurrencesResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``occurrences`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListNoteOccurrences`` requests and continue to iterate + through the ``occurrences`` field on the + corresponding responses. + + All the usual :class:`grafeas.grafeas_v1.types.ListNoteOccurrencesResponse` + 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[grafeas.ListNoteOccurrencesResponse]], + request: grafeas.ListNoteOccurrencesRequest, + response: grafeas.ListNoteOccurrencesResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = ()): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (grafeas.grafeas_v1.types.ListNoteOccurrencesRequest): + The initial request object. + response (grafeas.grafeas_v1.types.ListNoteOccurrencesResponse): + The initial response object. + retry (google.api_core.retry.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + self._method = method + self._request = grafeas.ListNoteOccurrencesRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[grafeas.ListNoteOccurrencesResponse]: + 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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) + yield self._response + def __aiter__(self) -> AsyncIterator[grafeas.Occurrence]: + async def async_generator(): + async for page in self.pages: + for response in page.occurrences: + 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/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/README.rst b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/README.rst new file mode 100644 index 000000000000..1085202fe2c8 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`GrafeasTransport` is the ABC for all transports. +- public child `GrafeasGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `GrafeasGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseGrafeasRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `GrafeasRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/__init__.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/__init__.py new file mode 100644 index 000000000000..af77bbdd97ec --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 GrafeasTransport +from .grpc import GrafeasGrpcTransport +from .grpc_asyncio import GrafeasGrpcAsyncIOTransport +from .rest import GrafeasRestTransport +from .rest import GrafeasRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[GrafeasTransport]] +_transport_registry['grpc'] = GrafeasGrpcTransport +_transport_registry['grpc_asyncio'] = GrafeasGrpcAsyncIOTransport +_transport_registry['rest'] = GrafeasRestTransport + +__all__ = ( + 'GrafeasTransport', + 'GrafeasGrpcTransport', + 'GrafeasGrpcAsyncIOTransport', + 'GrafeasRestTransport', + 'GrafeasRestInterceptor', +) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/base.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/base.py new file mode 100644 index 000000000000..6fbf36ad7b3d --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/base.py @@ -0,0 +1,416 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 grafeas.grafeas_v1 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.protobuf import empty_pb2 # type: ignore +from grafeas.grafeas_v1.types import grafeas + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class GrafeasTransport(abc.ABC): + """Abstract transport class for Grafeas.""" + + AUTH_SCOPES = ( + ) + + DEFAULT_HOST: str = 'containeranalysis.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 (default: 'containeranalysis.googleapis.com'). + 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 not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # 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 and not self._ignore_credentials: + 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 + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.get_occurrence: gapic_v1.method.wrap_method( + self.get_occurrence, + default_retry=retries.Retry( + initial=0.1, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.0, + client_info=client_info, + ), + self.list_occurrences: gapic_v1.method.wrap_method( + self.list_occurrences, + default_retry=retries.Retry( + initial=0.1, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.0, + client_info=client_info, + ), + self.delete_occurrence: gapic_v1.method.wrap_method( + self.delete_occurrence, + default_retry=retries.Retry( + initial=0.1, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.0, + client_info=client_info, + ), + self.create_occurrence: gapic_v1.method.wrap_method( + self.create_occurrence, + default_timeout=30.0, + client_info=client_info, + ), + self.batch_create_occurrences: gapic_v1.method.wrap_method( + self.batch_create_occurrences, + default_timeout=30.0, + client_info=client_info, + ), + self.update_occurrence: gapic_v1.method.wrap_method( + self.update_occurrence, + default_timeout=30.0, + client_info=client_info, + ), + self.get_occurrence_note: gapic_v1.method.wrap_method( + self.get_occurrence_note, + default_retry=retries.Retry( + initial=0.1, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.0, + client_info=client_info, + ), + self.get_note: gapic_v1.method.wrap_method( + self.get_note, + default_retry=retries.Retry( + initial=0.1, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.0, + client_info=client_info, + ), + self.list_notes: gapic_v1.method.wrap_method( + self.list_notes, + default_retry=retries.Retry( + initial=0.1, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.0, + client_info=client_info, + ), + self.delete_note: gapic_v1.method.wrap_method( + self.delete_note, + default_retry=retries.Retry( + initial=0.1, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.0, + client_info=client_info, + ), + self.create_note: gapic_v1.method.wrap_method( + self.create_note, + default_timeout=30.0, + client_info=client_info, + ), + self.batch_create_notes: gapic_v1.method.wrap_method( + self.batch_create_notes, + default_timeout=30.0, + client_info=client_info, + ), + self.update_note: gapic_v1.method.wrap_method( + self.update_note, + default_timeout=30.0, + client_info=client_info, + ), + self.list_note_occurrences: gapic_v1.method.wrap_method( + self.list_note_occurrences, + default_retry=retries.Retry( + initial=0.1, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.0, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def get_occurrence(self) -> Callable[ + [grafeas.GetOccurrenceRequest], + Union[ + grafeas.Occurrence, + Awaitable[grafeas.Occurrence] + ]]: + raise NotImplementedError() + + @property + def list_occurrences(self) -> Callable[ + [grafeas.ListOccurrencesRequest], + Union[ + grafeas.ListOccurrencesResponse, + Awaitable[grafeas.ListOccurrencesResponse] + ]]: + raise NotImplementedError() + + @property + def delete_occurrence(self) -> Callable[ + [grafeas.DeleteOccurrenceRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def create_occurrence(self) -> Callable[ + [grafeas.CreateOccurrenceRequest], + Union[ + grafeas.Occurrence, + Awaitable[grafeas.Occurrence] + ]]: + raise NotImplementedError() + + @property + def batch_create_occurrences(self) -> Callable[ + [grafeas.BatchCreateOccurrencesRequest], + Union[ + grafeas.BatchCreateOccurrencesResponse, + Awaitable[grafeas.BatchCreateOccurrencesResponse] + ]]: + raise NotImplementedError() + + @property + def update_occurrence(self) -> Callable[ + [grafeas.UpdateOccurrenceRequest], + Union[ + grafeas.Occurrence, + Awaitable[grafeas.Occurrence] + ]]: + raise NotImplementedError() + + @property + def get_occurrence_note(self) -> Callable[ + [grafeas.GetOccurrenceNoteRequest], + Union[ + grafeas.Note, + Awaitable[grafeas.Note] + ]]: + raise NotImplementedError() + + @property + def get_note(self) -> Callable[ + [grafeas.GetNoteRequest], + Union[ + grafeas.Note, + Awaitable[grafeas.Note] + ]]: + raise NotImplementedError() + + @property + def list_notes(self) -> Callable[ + [grafeas.ListNotesRequest], + Union[ + grafeas.ListNotesResponse, + Awaitable[grafeas.ListNotesResponse] + ]]: + raise NotImplementedError() + + @property + def delete_note(self) -> Callable[ + [grafeas.DeleteNoteRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def create_note(self) -> Callable[ + [grafeas.CreateNoteRequest], + Union[ + grafeas.Note, + Awaitable[grafeas.Note] + ]]: + raise NotImplementedError() + + @property + def batch_create_notes(self) -> Callable[ + [grafeas.BatchCreateNotesRequest], + Union[ + grafeas.BatchCreateNotesResponse, + Awaitable[grafeas.BatchCreateNotesResponse] + ]]: + raise NotImplementedError() + + @property + def update_note(self) -> Callable[ + [grafeas.UpdateNoteRequest], + Union[ + grafeas.Note, + Awaitable[grafeas.Note] + ]]: + raise NotImplementedError() + + @property + def list_note_occurrences(self) -> Callable[ + [grafeas.ListNoteOccurrencesRequest], + Union[ + grafeas.ListNoteOccurrencesResponse, + Awaitable[grafeas.ListNoteOccurrencesResponse] + ]]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'GrafeasTransport', +) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc.py new file mode 100644 index 000000000000..5c1c9e6c0bde --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc.py @@ -0,0 +1,631 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.protobuf import empty_pb2 # type: ignore +from grafeas.grafeas_v1.types import grafeas +from .base import GrafeasTransport, DEFAULT_CLIENT_INFO + + +class GrafeasGrpcTransport(GrafeasTransport): + """gRPC backend transport for Grafeas. + + `Grafeas `__ API. + + Retrieves analysis results of Cloud components such as Docker + container images. + + Analysis results are stored as a series of occurrences. An + ``Occurrence`` contains information about a specific analysis + instance on a resource. An occurrence refers to a ``Note``. A note + contains details describing the analysis and is generally stored in + a separate project, called a ``Provider``. Multiple occurrences can + refer to the same note. + + For example, an SSL vulnerability could affect multiple images. In + this case, there would be one note for the vulnerability and an + occurrence for each image with the vulnerability referring to that + note. + + 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 = 'containeranalysis.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[grpc.Channel, Callable[..., 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 (default: 'containeranalysis.googleapis.com'). + 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 a ``channel`` instance 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 a ``channel`` instance is provided. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # 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: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + 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 = 'containeranalysis.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 get_occurrence(self) -> Callable[ + [grafeas.GetOccurrenceRequest], + grafeas.Occurrence]: + r"""Return a callable for the get occurrence method over gRPC. + + Gets the specified occurrence. + + Returns: + Callable[[~.GetOccurrenceRequest], + ~.Occurrence]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_occurrence' not in self._stubs: + self._stubs['get_occurrence'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/GetOccurrence', + request_serializer=grafeas.GetOccurrenceRequest.serialize, + response_deserializer=grafeas.Occurrence.deserialize, + ) + return self._stubs['get_occurrence'] + + @property + def list_occurrences(self) -> Callable[ + [grafeas.ListOccurrencesRequest], + grafeas.ListOccurrencesResponse]: + r"""Return a callable for the list occurrences method over gRPC. + + Lists occurrences for the specified project. + + Returns: + Callable[[~.ListOccurrencesRequest], + ~.ListOccurrencesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_occurrences' not in self._stubs: + self._stubs['list_occurrences'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/ListOccurrences', + request_serializer=grafeas.ListOccurrencesRequest.serialize, + response_deserializer=grafeas.ListOccurrencesResponse.deserialize, + ) + return self._stubs['list_occurrences'] + + @property + def delete_occurrence(self) -> Callable[ + [grafeas.DeleteOccurrenceRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete occurrence method over gRPC. + + Deletes the specified occurrence. For example, use + this method to delete an occurrence when the occurrence + is no longer applicable for the given resource. + + Returns: + Callable[[~.DeleteOccurrenceRequest], + ~.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_occurrence' not in self._stubs: + self._stubs['delete_occurrence'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/DeleteOccurrence', + request_serializer=grafeas.DeleteOccurrenceRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_occurrence'] + + @property + def create_occurrence(self) -> Callable[ + [grafeas.CreateOccurrenceRequest], + grafeas.Occurrence]: + r"""Return a callable for the create occurrence method over gRPC. + + Creates a new occurrence. + + Returns: + Callable[[~.CreateOccurrenceRequest], + ~.Occurrence]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_occurrence' not in self._stubs: + self._stubs['create_occurrence'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/CreateOccurrence', + request_serializer=grafeas.CreateOccurrenceRequest.serialize, + response_deserializer=grafeas.Occurrence.deserialize, + ) + return self._stubs['create_occurrence'] + + @property + def batch_create_occurrences(self) -> Callable[ + [grafeas.BatchCreateOccurrencesRequest], + grafeas.BatchCreateOccurrencesResponse]: + r"""Return a callable for the batch create occurrences method over gRPC. + + Creates new occurrences in batch. + + Returns: + Callable[[~.BatchCreateOccurrencesRequest], + ~.BatchCreateOccurrencesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_create_occurrences' not in self._stubs: + self._stubs['batch_create_occurrences'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/BatchCreateOccurrences', + request_serializer=grafeas.BatchCreateOccurrencesRequest.serialize, + response_deserializer=grafeas.BatchCreateOccurrencesResponse.deserialize, + ) + return self._stubs['batch_create_occurrences'] + + @property + def update_occurrence(self) -> Callable[ + [grafeas.UpdateOccurrenceRequest], + grafeas.Occurrence]: + r"""Return a callable for the update occurrence method over gRPC. + + Updates the specified occurrence. + + Returns: + Callable[[~.UpdateOccurrenceRequest], + ~.Occurrence]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_occurrence' not in self._stubs: + self._stubs['update_occurrence'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/UpdateOccurrence', + request_serializer=grafeas.UpdateOccurrenceRequest.serialize, + response_deserializer=grafeas.Occurrence.deserialize, + ) + return self._stubs['update_occurrence'] + + @property + def get_occurrence_note(self) -> Callable[ + [grafeas.GetOccurrenceNoteRequest], + grafeas.Note]: + r"""Return a callable for the get occurrence note method over gRPC. + + Gets the note attached to the specified occurrence. + Consumer projects can use this method to get a note that + belongs to a provider project. + + Returns: + Callable[[~.GetOccurrenceNoteRequest], + ~.Note]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_occurrence_note' not in self._stubs: + self._stubs['get_occurrence_note'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/GetOccurrenceNote', + request_serializer=grafeas.GetOccurrenceNoteRequest.serialize, + response_deserializer=grafeas.Note.deserialize, + ) + return self._stubs['get_occurrence_note'] + + @property + def get_note(self) -> Callable[ + [grafeas.GetNoteRequest], + grafeas.Note]: + r"""Return a callable for the get note method over gRPC. + + Gets the specified note. + + Returns: + Callable[[~.GetNoteRequest], + ~.Note]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_note' not in self._stubs: + self._stubs['get_note'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/GetNote', + request_serializer=grafeas.GetNoteRequest.serialize, + response_deserializer=grafeas.Note.deserialize, + ) + return self._stubs['get_note'] + + @property + def list_notes(self) -> Callable[ + [grafeas.ListNotesRequest], + grafeas.ListNotesResponse]: + r"""Return a callable for the list notes method over gRPC. + + Lists notes for the specified project. + + Returns: + Callable[[~.ListNotesRequest], + ~.ListNotesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_notes' not in self._stubs: + self._stubs['list_notes'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/ListNotes', + request_serializer=grafeas.ListNotesRequest.serialize, + response_deserializer=grafeas.ListNotesResponse.deserialize, + ) + return self._stubs['list_notes'] + + @property + def delete_note(self) -> Callable[ + [grafeas.DeleteNoteRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete note method over gRPC. + + Deletes the specified note. + + Returns: + Callable[[~.DeleteNoteRequest], + ~.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_note' not in self._stubs: + self._stubs['delete_note'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/DeleteNote', + request_serializer=grafeas.DeleteNoteRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_note'] + + @property + def create_note(self) -> Callable[ + [grafeas.CreateNoteRequest], + grafeas.Note]: + r"""Return a callable for the create note method over gRPC. + + Creates a new note. + + Returns: + Callable[[~.CreateNoteRequest], + ~.Note]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_note' not in self._stubs: + self._stubs['create_note'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/CreateNote', + request_serializer=grafeas.CreateNoteRequest.serialize, + response_deserializer=grafeas.Note.deserialize, + ) + return self._stubs['create_note'] + + @property + def batch_create_notes(self) -> Callable[ + [grafeas.BatchCreateNotesRequest], + grafeas.BatchCreateNotesResponse]: + r"""Return a callable for the batch create notes method over gRPC. + + Creates new notes in batch. + + Returns: + Callable[[~.BatchCreateNotesRequest], + ~.BatchCreateNotesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_create_notes' not in self._stubs: + self._stubs['batch_create_notes'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/BatchCreateNotes', + request_serializer=grafeas.BatchCreateNotesRequest.serialize, + response_deserializer=grafeas.BatchCreateNotesResponse.deserialize, + ) + return self._stubs['batch_create_notes'] + + @property + def update_note(self) -> Callable[ + [grafeas.UpdateNoteRequest], + grafeas.Note]: + r"""Return a callable for the update note method over gRPC. + + Updates the specified note. + + Returns: + Callable[[~.UpdateNoteRequest], + ~.Note]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_note' not in self._stubs: + self._stubs['update_note'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/UpdateNote', + request_serializer=grafeas.UpdateNoteRequest.serialize, + response_deserializer=grafeas.Note.deserialize, + ) + return self._stubs['update_note'] + + @property + def list_note_occurrences(self) -> Callable[ + [grafeas.ListNoteOccurrencesRequest], + grafeas.ListNoteOccurrencesResponse]: + r"""Return a callable for the list note occurrences method over gRPC. + + Lists occurrences referencing the specified note. + Provider projects can use this method to get all + occurrences across consumer projects referencing the + specified note. + + Returns: + Callable[[~.ListNoteOccurrencesRequest], + ~.ListNoteOccurrencesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_note_occurrences' not in self._stubs: + self._stubs['list_note_occurrences'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/ListNoteOccurrences', + request_serializer=grafeas.ListNoteOccurrencesRequest.serialize, + response_deserializer=grafeas.ListNoteOccurrencesResponse.deserialize, + ) + return self._stubs['list_note_occurrences'] + + def close(self): + self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'GrafeasGrpcTransport', +) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py new file mode 100644 index 000000000000..b927b81553b6 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py @@ -0,0 +1,797 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 inspect +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 exceptions as core_exceptions +from google.api_core import retry_async as retries +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.protobuf import empty_pb2 # type: ignore +from grafeas.grafeas_v1.types import grafeas +from .base import GrafeasTransport, DEFAULT_CLIENT_INFO +from .grpc import GrafeasGrpcTransport + + +class GrafeasGrpcAsyncIOTransport(GrafeasTransport): + """gRPC AsyncIO backend transport for Grafeas. + + `Grafeas `__ API. + + Retrieves analysis results of Cloud components such as Docker + container images. + + Analysis results are stored as a series of occurrences. An + ``Occurrence`` contains information about a specific analysis + instance on a resource. An occurrence refers to a ``Note``. A note + contains details describing the analysis and is generally stored in + a separate project, called a ``Provider``. Multiple occurrences can + refer to the same note. + + For example, an SSL vulnerability could affect multiple images. In + this case, there would be one note for the vulnerability and an + occurrence for each image with the vulnerability referring to that + note. + + 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 = 'containeranalysis.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`. + 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 = 'containeranalysis.googleapis.com', + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[Union[aio.Channel, Callable[..., 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 (default: 'containeranalysis.googleapis.com'). + 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 a ``channel`` instance 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 a ``channel`` instance 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[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # 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: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + 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._wrap_with_kind = "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters + 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 get_occurrence(self) -> Callable[ + [grafeas.GetOccurrenceRequest], + Awaitable[grafeas.Occurrence]]: + r"""Return a callable for the get occurrence method over gRPC. + + Gets the specified occurrence. + + Returns: + Callable[[~.GetOccurrenceRequest], + Awaitable[~.Occurrence]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_occurrence' not in self._stubs: + self._stubs['get_occurrence'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/GetOccurrence', + request_serializer=grafeas.GetOccurrenceRequest.serialize, + response_deserializer=grafeas.Occurrence.deserialize, + ) + return self._stubs['get_occurrence'] + + @property + def list_occurrences(self) -> Callable[ + [grafeas.ListOccurrencesRequest], + Awaitable[grafeas.ListOccurrencesResponse]]: + r"""Return a callable for the list occurrences method over gRPC. + + Lists occurrences for the specified project. + + Returns: + Callable[[~.ListOccurrencesRequest], + Awaitable[~.ListOccurrencesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_occurrences' not in self._stubs: + self._stubs['list_occurrences'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/ListOccurrences', + request_serializer=grafeas.ListOccurrencesRequest.serialize, + response_deserializer=grafeas.ListOccurrencesResponse.deserialize, + ) + return self._stubs['list_occurrences'] + + @property + def delete_occurrence(self) -> Callable[ + [grafeas.DeleteOccurrenceRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete occurrence method over gRPC. + + Deletes the specified occurrence. For example, use + this method to delete an occurrence when the occurrence + is no longer applicable for the given resource. + + Returns: + Callable[[~.DeleteOccurrenceRequest], + 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_occurrence' not in self._stubs: + self._stubs['delete_occurrence'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/DeleteOccurrence', + request_serializer=grafeas.DeleteOccurrenceRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_occurrence'] + + @property + def create_occurrence(self) -> Callable[ + [grafeas.CreateOccurrenceRequest], + Awaitable[grafeas.Occurrence]]: + r"""Return a callable for the create occurrence method over gRPC. + + Creates a new occurrence. + + Returns: + Callable[[~.CreateOccurrenceRequest], + Awaitable[~.Occurrence]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_occurrence' not in self._stubs: + self._stubs['create_occurrence'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/CreateOccurrence', + request_serializer=grafeas.CreateOccurrenceRequest.serialize, + response_deserializer=grafeas.Occurrence.deserialize, + ) + return self._stubs['create_occurrence'] + + @property + def batch_create_occurrences(self) -> Callable[ + [grafeas.BatchCreateOccurrencesRequest], + Awaitable[grafeas.BatchCreateOccurrencesResponse]]: + r"""Return a callable for the batch create occurrences method over gRPC. + + Creates new occurrences in batch. + + Returns: + Callable[[~.BatchCreateOccurrencesRequest], + Awaitable[~.BatchCreateOccurrencesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_create_occurrences' not in self._stubs: + self._stubs['batch_create_occurrences'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/BatchCreateOccurrences', + request_serializer=grafeas.BatchCreateOccurrencesRequest.serialize, + response_deserializer=grafeas.BatchCreateOccurrencesResponse.deserialize, + ) + return self._stubs['batch_create_occurrences'] + + @property + def update_occurrence(self) -> Callable[ + [grafeas.UpdateOccurrenceRequest], + Awaitable[grafeas.Occurrence]]: + r"""Return a callable for the update occurrence method over gRPC. + + Updates the specified occurrence. + + Returns: + Callable[[~.UpdateOccurrenceRequest], + Awaitable[~.Occurrence]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_occurrence' not in self._stubs: + self._stubs['update_occurrence'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/UpdateOccurrence', + request_serializer=grafeas.UpdateOccurrenceRequest.serialize, + response_deserializer=grafeas.Occurrence.deserialize, + ) + return self._stubs['update_occurrence'] + + @property + def get_occurrence_note(self) -> Callable[ + [grafeas.GetOccurrenceNoteRequest], + Awaitable[grafeas.Note]]: + r"""Return a callable for the get occurrence note method over gRPC. + + Gets the note attached to the specified occurrence. + Consumer projects can use this method to get a note that + belongs to a provider project. + + Returns: + Callable[[~.GetOccurrenceNoteRequest], + Awaitable[~.Note]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_occurrence_note' not in self._stubs: + self._stubs['get_occurrence_note'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/GetOccurrenceNote', + request_serializer=grafeas.GetOccurrenceNoteRequest.serialize, + response_deserializer=grafeas.Note.deserialize, + ) + return self._stubs['get_occurrence_note'] + + @property + def get_note(self) -> Callable[ + [grafeas.GetNoteRequest], + Awaitable[grafeas.Note]]: + r"""Return a callable for the get note method over gRPC. + + Gets the specified note. + + Returns: + Callable[[~.GetNoteRequest], + Awaitable[~.Note]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_note' not in self._stubs: + self._stubs['get_note'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/GetNote', + request_serializer=grafeas.GetNoteRequest.serialize, + response_deserializer=grafeas.Note.deserialize, + ) + return self._stubs['get_note'] + + @property + def list_notes(self) -> Callable[ + [grafeas.ListNotesRequest], + Awaitable[grafeas.ListNotesResponse]]: + r"""Return a callable for the list notes method over gRPC. + + Lists notes for the specified project. + + Returns: + Callable[[~.ListNotesRequest], + Awaitable[~.ListNotesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_notes' not in self._stubs: + self._stubs['list_notes'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/ListNotes', + request_serializer=grafeas.ListNotesRequest.serialize, + response_deserializer=grafeas.ListNotesResponse.deserialize, + ) + return self._stubs['list_notes'] + + @property + def delete_note(self) -> Callable[ + [grafeas.DeleteNoteRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete note method over gRPC. + + Deletes the specified note. + + Returns: + Callable[[~.DeleteNoteRequest], + 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_note' not in self._stubs: + self._stubs['delete_note'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/DeleteNote', + request_serializer=grafeas.DeleteNoteRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_note'] + + @property + def create_note(self) -> Callable[ + [grafeas.CreateNoteRequest], + Awaitable[grafeas.Note]]: + r"""Return a callable for the create note method over gRPC. + + Creates a new note. + + Returns: + Callable[[~.CreateNoteRequest], + Awaitable[~.Note]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_note' not in self._stubs: + self._stubs['create_note'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/CreateNote', + request_serializer=grafeas.CreateNoteRequest.serialize, + response_deserializer=grafeas.Note.deserialize, + ) + return self._stubs['create_note'] + + @property + def batch_create_notes(self) -> Callable[ + [grafeas.BatchCreateNotesRequest], + Awaitable[grafeas.BatchCreateNotesResponse]]: + r"""Return a callable for the batch create notes method over gRPC. + + Creates new notes in batch. + + Returns: + Callable[[~.BatchCreateNotesRequest], + Awaitable[~.BatchCreateNotesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_create_notes' not in self._stubs: + self._stubs['batch_create_notes'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/BatchCreateNotes', + request_serializer=grafeas.BatchCreateNotesRequest.serialize, + response_deserializer=grafeas.BatchCreateNotesResponse.deserialize, + ) + return self._stubs['batch_create_notes'] + + @property + def update_note(self) -> Callable[ + [grafeas.UpdateNoteRequest], + Awaitable[grafeas.Note]]: + r"""Return a callable for the update note method over gRPC. + + Updates the specified note. + + Returns: + Callable[[~.UpdateNoteRequest], + Awaitable[~.Note]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_note' not in self._stubs: + self._stubs['update_note'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/UpdateNote', + request_serializer=grafeas.UpdateNoteRequest.serialize, + response_deserializer=grafeas.Note.deserialize, + ) + return self._stubs['update_note'] + + @property + def list_note_occurrences(self) -> Callable[ + [grafeas.ListNoteOccurrencesRequest], + Awaitable[grafeas.ListNoteOccurrencesResponse]]: + r"""Return a callable for the list note occurrences method over gRPC. + + Lists occurrences referencing the specified note. + Provider projects can use this method to get all + occurrences across consumer projects referencing the + specified note. + + Returns: + Callable[[~.ListNoteOccurrencesRequest], + Awaitable[~.ListNoteOccurrencesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_note_occurrences' not in self._stubs: + self._stubs['list_note_occurrences'] = self.grpc_channel.unary_unary( + '/grafeas.v1.Grafeas/ListNoteOccurrences', + request_serializer=grafeas.ListNoteOccurrencesRequest.serialize, + response_deserializer=grafeas.ListNoteOccurrencesResponse.deserialize, + ) + return self._stubs['list_note_occurrences'] + + def _prep_wrapped_messages(self, client_info): + """ Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.get_occurrence: self._wrap_method( + self.get_occurrence, + default_retry=retries.AsyncRetry( + initial=0.1, + maximum=60.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.list_occurrences: self._wrap_method( + self.list_occurrences, + default_retry=retries.AsyncRetry( + initial=0.1, + maximum=60.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.delete_occurrence: self._wrap_method( + self.delete_occurrence, + default_retry=retries.AsyncRetry( + initial=0.1, + maximum=60.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.create_occurrence: self._wrap_method( + self.create_occurrence, + default_timeout=30.0, + client_info=client_info, + ), + self.batch_create_occurrences: self._wrap_method( + self.batch_create_occurrences, + default_timeout=30.0, + client_info=client_info, + ), + self.update_occurrence: self._wrap_method( + self.update_occurrence, + default_timeout=30.0, + client_info=client_info, + ), + self.get_occurrence_note: self._wrap_method( + self.get_occurrence_note, + default_retry=retries.AsyncRetry( + initial=0.1, + maximum=60.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.get_note: self._wrap_method( + self.get_note, + default_retry=retries.AsyncRetry( + initial=0.1, + maximum=60.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.list_notes: self._wrap_method( + self.list_notes, + default_retry=retries.AsyncRetry( + initial=0.1, + maximum=60.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.delete_note: self._wrap_method( + self.delete_note, + default_retry=retries.AsyncRetry( + initial=0.1, + maximum=60.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.create_note: self._wrap_method( + self.create_note, + default_timeout=30.0, + client_info=client_info, + ), + self.batch_create_notes: self._wrap_method( + self.batch_create_notes, + default_timeout=30.0, + client_info=client_info, + ), + self.update_note: self._wrap_method( + self.update_note, + default_timeout=30.0, + client_info=client_info, + ), + self.list_note_occurrences: self._wrap_method( + self.list_note_occurrences, + default_retry=retries.AsyncRetry( + initial=0.1, + maximum=60.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, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self.grpc_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ( + 'GrafeasGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest.py new file mode 100644 index 000000000000..a3a7d2a3724b --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest.py @@ -0,0 +1,1629 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 +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 gapic_v1 + +from google.protobuf import json_format + +from requests import __version__ as requests_version +import dataclasses +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + + +from google.protobuf import empty_pb2 # type: ignore +from grafeas.grafeas_v1.types import grafeas + + +from .rest_base import _BaseGrafeasRestTransport +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + + +class GrafeasRestInterceptor: + """Interceptor for Grafeas. + + 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 GrafeasRestTransport. + + .. code-block:: python + class MyCustomGrafeasInterceptor(GrafeasRestInterceptor): + def pre_batch_create_notes(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_create_notes(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_create_occurrences(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_create_occurrences(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_note(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_note(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_occurrence(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_occurrence(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_note(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_delete_occurrence(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_note(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_note(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_occurrence(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_occurrence(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_occurrence_note(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_occurrence_note(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_note_occurrences(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_note_occurrences(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_notes(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_notes(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_occurrences(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_occurrences(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_note(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_note(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_occurrence(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_occurrence(self, response): + logging.log(f"Received response: {response}") + return response + + transport = GrafeasRestTransport(interceptor=MyCustomGrafeasInterceptor()) + client = GrafeasClient(transport=transport) + + + """ + def pre_batch_create_notes(self, request: grafeas.BatchCreateNotesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.BatchCreateNotesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for batch_create_notes + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def post_batch_create_notes(self, response: grafeas.BatchCreateNotesResponse) -> grafeas.BatchCreateNotesResponse: + """Post-rpc interceptor for batch_create_notes + + Override in a subclass to manipulate the response + after it is returned by the Grafeas server but before + it is returned to user code. + """ + return response + + def pre_batch_create_occurrences(self, request: grafeas.BatchCreateOccurrencesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.BatchCreateOccurrencesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for batch_create_occurrences + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def post_batch_create_occurrences(self, response: grafeas.BatchCreateOccurrencesResponse) -> grafeas.BatchCreateOccurrencesResponse: + """Post-rpc interceptor for batch_create_occurrences + + Override in a subclass to manipulate the response + after it is returned by the Grafeas server but before + it is returned to user code. + """ + return response + + def pre_create_note(self, request: grafeas.CreateNoteRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.CreateNoteRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_note + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def post_create_note(self, response: grafeas.Note) -> grafeas.Note: + """Post-rpc interceptor for create_note + + Override in a subclass to manipulate the response + after it is returned by the Grafeas server but before + it is returned to user code. + """ + return response + + def pre_create_occurrence(self, request: grafeas.CreateOccurrenceRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.CreateOccurrenceRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_occurrence + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def post_create_occurrence(self, response: grafeas.Occurrence) -> grafeas.Occurrence: + """Post-rpc interceptor for create_occurrence + + Override in a subclass to manipulate the response + after it is returned by the Grafeas server but before + it is returned to user code. + """ + return response + + def pre_delete_note(self, request: grafeas.DeleteNoteRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.DeleteNoteRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_note + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def pre_delete_occurrence(self, request: grafeas.DeleteOccurrenceRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.DeleteOccurrenceRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_occurrence + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def pre_get_note(self, request: grafeas.GetNoteRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.GetNoteRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_note + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def post_get_note(self, response: grafeas.Note) -> grafeas.Note: + """Post-rpc interceptor for get_note + + Override in a subclass to manipulate the response + after it is returned by the Grafeas server but before + it is returned to user code. + """ + return response + + def pre_get_occurrence(self, request: grafeas.GetOccurrenceRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.GetOccurrenceRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_occurrence + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def post_get_occurrence(self, response: grafeas.Occurrence) -> grafeas.Occurrence: + """Post-rpc interceptor for get_occurrence + + Override in a subclass to manipulate the response + after it is returned by the Grafeas server but before + it is returned to user code. + """ + return response + + def pre_get_occurrence_note(self, request: grafeas.GetOccurrenceNoteRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.GetOccurrenceNoteRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_occurrence_note + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def post_get_occurrence_note(self, response: grafeas.Note) -> grafeas.Note: + """Post-rpc interceptor for get_occurrence_note + + Override in a subclass to manipulate the response + after it is returned by the Grafeas server but before + it is returned to user code. + """ + return response + + def pre_list_note_occurrences(self, request: grafeas.ListNoteOccurrencesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.ListNoteOccurrencesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_note_occurrences + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def post_list_note_occurrences(self, response: grafeas.ListNoteOccurrencesResponse) -> grafeas.ListNoteOccurrencesResponse: + """Post-rpc interceptor for list_note_occurrences + + Override in a subclass to manipulate the response + after it is returned by the Grafeas server but before + it is returned to user code. + """ + return response + + def pre_list_notes(self, request: grafeas.ListNotesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.ListNotesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_notes + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def post_list_notes(self, response: grafeas.ListNotesResponse) -> grafeas.ListNotesResponse: + """Post-rpc interceptor for list_notes + + Override in a subclass to manipulate the response + after it is returned by the Grafeas server but before + it is returned to user code. + """ + return response + + def pre_list_occurrences(self, request: grafeas.ListOccurrencesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.ListOccurrencesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_occurrences + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def post_list_occurrences(self, response: grafeas.ListOccurrencesResponse) -> grafeas.ListOccurrencesResponse: + """Post-rpc interceptor for list_occurrences + + Override in a subclass to manipulate the response + after it is returned by the Grafeas server but before + it is returned to user code. + """ + return response + + def pre_update_note(self, request: grafeas.UpdateNoteRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.UpdateNoteRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_note + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def post_update_note(self, response: grafeas.Note) -> grafeas.Note: + """Post-rpc interceptor for update_note + + Override in a subclass to manipulate the response + after it is returned by the Grafeas server but before + it is returned to user code. + """ + return response + + def pre_update_occurrence(self, request: grafeas.UpdateOccurrenceRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.UpdateOccurrenceRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_occurrence + + Override in a subclass to manipulate the request or metadata + before they are sent to the Grafeas server. + """ + return request, metadata + + def post_update_occurrence(self, response: grafeas.Occurrence) -> grafeas.Occurrence: + """Post-rpc interceptor for update_occurrence + + Override in a subclass to manipulate the response + after it is returned by the Grafeas server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class GrafeasRestStub: + _session: AuthorizedSession + _host: str + _interceptor: GrafeasRestInterceptor + + +class GrafeasRestTransport(_BaseGrafeasRestTransport): + """REST backend synchronous transport for Grafeas. + + `Grafeas `__ API. + + Retrieves analysis results of Cloud components such as Docker + container images. + + Analysis results are stored as a series of occurrences. An + ``Occurrence`` contains information about a specific analysis + instance on a resource. An occurrence refers to a ``Note``. A note + contains details describing the analysis and is generally stored in + a separate project, called a ``Provider``. Multiple occurrences can + refer to the same note. + + For example, an SSL vulnerability could affect multiple images. In + this case, there would be one note for the vulnerability and an + occurrence for each image with the vulnerability referring to that + note. + + 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 = 'containeranalysis.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[GrafeasRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'containeranalysis.googleapis.com'). + 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 + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + 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 GrafeasRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _BatchCreateNotes(_BaseGrafeasRestTransport._BaseBatchCreateNotes, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.BatchCreateNotes") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__(self, + request: grafeas.BatchCreateNotesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> grafeas.BatchCreateNotesResponse: + r"""Call the batch create notes method over HTTP. + + Args: + request (~.grafeas.BatchCreateNotesRequest): + The request object. Request to create notes in batch. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.grafeas.BatchCreateNotesResponse: + Response for creating notes in batch. + """ + + http_options = _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_http_options() + request, metadata = self._interceptor.pre_batch_create_notes(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_transcoded_request(http_options, request) + + body = _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_request_body_json(transcoded_request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._BatchCreateNotes._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = grafeas.BatchCreateNotesResponse() + pb_resp = grafeas.BatchCreateNotesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_create_notes(resp) + return resp + + class _BatchCreateOccurrences(_BaseGrafeasRestTransport._BaseBatchCreateOccurrences, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.BatchCreateOccurrences") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__(self, + request: grafeas.BatchCreateOccurrencesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> grafeas.BatchCreateOccurrencesResponse: + r"""Call the batch create occurrences method over HTTP. + + Args: + request (~.grafeas.BatchCreateOccurrencesRequest): + The request object. Request to create occurrences in + batch. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.grafeas.BatchCreateOccurrencesResponse: + Response for creating occurrences in + batch. + + """ + + http_options = _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_http_options() + request, metadata = self._interceptor.pre_batch_create_occurrences(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_transcoded_request(http_options, request) + + body = _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_request_body_json(transcoded_request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._BatchCreateOccurrences._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = grafeas.BatchCreateOccurrencesResponse() + pb_resp = grafeas.BatchCreateOccurrencesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_create_occurrences(resp) + return resp + + class _CreateNote(_BaseGrafeasRestTransport._BaseCreateNote, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.CreateNote") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__(self, + request: grafeas.CreateNoteRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> grafeas.Note: + r"""Call the create note method over HTTP. + + Args: + request (~.grafeas.CreateNoteRequest): + The request object. Request to create a new note. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.grafeas.Note: + A type of analysis that can be done + for a resource. + + """ + + http_options = _BaseGrafeasRestTransport._BaseCreateNote._get_http_options() + request, metadata = self._interceptor.pre_create_note(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseCreateNote._get_transcoded_request(http_options, request) + + body = _BaseGrafeasRestTransport._BaseCreateNote._get_request_body_json(transcoded_request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseCreateNote._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._CreateNote._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = grafeas.Note() + pb_resp = grafeas.Note.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_note(resp) + return resp + + class _CreateOccurrence(_BaseGrafeasRestTransport._BaseCreateOccurrence, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.CreateOccurrence") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__(self, + request: grafeas.CreateOccurrenceRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> grafeas.Occurrence: + r"""Call the create occurrence method over HTTP. + + Args: + request (~.grafeas.CreateOccurrenceRequest): + The request object. Request to create a new occurrence. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.grafeas.Occurrence: + An instance of an analysis type that + has been found on a resource. + + """ + + http_options = _BaseGrafeasRestTransport._BaseCreateOccurrence._get_http_options() + request, metadata = self._interceptor.pre_create_occurrence(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseCreateOccurrence._get_transcoded_request(http_options, request) + + body = _BaseGrafeasRestTransport._BaseCreateOccurrence._get_request_body_json(transcoded_request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseCreateOccurrence._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._CreateOccurrence._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = grafeas.Occurrence() + pb_resp = grafeas.Occurrence.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_occurrence(resp) + return resp + + class _DeleteNote(_BaseGrafeasRestTransport._BaseDeleteNote, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.DeleteNote") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__(self, + request: grafeas.DeleteNoteRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete note method over HTTP. + + Args: + request (~.grafeas.DeleteNoteRequest): + The request object. Request to delete a note. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be 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 = _BaseGrafeasRestTransport._BaseDeleteNote._get_http_options() + request, metadata = self._interceptor.pre_delete_note(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseDeleteNote._get_transcoded_request(http_options, request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseDeleteNote._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._DeleteNote._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) + + # 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 _DeleteOccurrence(_BaseGrafeasRestTransport._BaseDeleteOccurrence, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.DeleteOccurrence") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__(self, + request: grafeas.DeleteOccurrenceRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete occurrence method over HTTP. + + Args: + request (~.grafeas.DeleteOccurrenceRequest): + The request object. Request to delete an occurrence. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be 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 = _BaseGrafeasRestTransport._BaseDeleteOccurrence._get_http_options() + request, metadata = self._interceptor.pre_delete_occurrence(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseDeleteOccurrence._get_transcoded_request(http_options, request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseDeleteOccurrence._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._DeleteOccurrence._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) + + # 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 _GetNote(_BaseGrafeasRestTransport._BaseGetNote, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.GetNote") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__(self, + request: grafeas.GetNoteRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> grafeas.Note: + r"""Call the get note method over HTTP. + + Args: + request (~.grafeas.GetNoteRequest): + The request object. Request to get a note. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.grafeas.Note: + A type of analysis that can be done + for a resource. + + """ + + http_options = _BaseGrafeasRestTransport._BaseGetNote._get_http_options() + request, metadata = self._interceptor.pre_get_note(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseGetNote._get_transcoded_request(http_options, request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseGetNote._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._GetNote._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) + + # 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 = grafeas.Note() + pb_resp = grafeas.Note.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_note(resp) + return resp + + class _GetOccurrence(_BaseGrafeasRestTransport._BaseGetOccurrence, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.GetOccurrence") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__(self, + request: grafeas.GetOccurrenceRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> grafeas.Occurrence: + r"""Call the get occurrence method over HTTP. + + Args: + request (~.grafeas.GetOccurrenceRequest): + The request object. Request to get an occurrence. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.grafeas.Occurrence: + An instance of an analysis type that + has been found on a resource. + + """ + + http_options = _BaseGrafeasRestTransport._BaseGetOccurrence._get_http_options() + request, metadata = self._interceptor.pre_get_occurrence(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseGetOccurrence._get_transcoded_request(http_options, request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseGetOccurrence._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._GetOccurrence._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) + + # 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 = grafeas.Occurrence() + pb_resp = grafeas.Occurrence.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_occurrence(resp) + return resp + + class _GetOccurrenceNote(_BaseGrafeasRestTransport._BaseGetOccurrenceNote, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.GetOccurrenceNote") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__(self, + request: grafeas.GetOccurrenceNoteRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> grafeas.Note: + r"""Call the get occurrence note method over HTTP. + + Args: + request (~.grafeas.GetOccurrenceNoteRequest): + The request object. Request to get the note to which the + specified occurrence is attached. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.grafeas.Note: + A type of analysis that can be done + for a resource. + + """ + + http_options = _BaseGrafeasRestTransport._BaseGetOccurrenceNote._get_http_options() + request, metadata = self._interceptor.pre_get_occurrence_note(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseGetOccurrenceNote._get_transcoded_request(http_options, request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseGetOccurrenceNote._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._GetOccurrenceNote._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) + + # 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 = grafeas.Note() + pb_resp = grafeas.Note.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_occurrence_note(resp) + return resp + + class _ListNoteOccurrences(_BaseGrafeasRestTransport._BaseListNoteOccurrences, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.ListNoteOccurrences") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__(self, + request: grafeas.ListNoteOccurrencesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> grafeas.ListNoteOccurrencesResponse: + r"""Call the list note occurrences method over HTTP. + + Args: + request (~.grafeas.ListNoteOccurrencesRequest): + The request object. Request to list occurrences for a + note. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.grafeas.ListNoteOccurrencesResponse: + Response for listing occurrences for + a note. + + """ + + http_options = _BaseGrafeasRestTransport._BaseListNoteOccurrences._get_http_options() + request, metadata = self._interceptor.pre_list_note_occurrences(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseListNoteOccurrences._get_transcoded_request(http_options, request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseListNoteOccurrences._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._ListNoteOccurrences._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) + + # 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 = grafeas.ListNoteOccurrencesResponse() + pb_resp = grafeas.ListNoteOccurrencesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_note_occurrences(resp) + return resp + + class _ListNotes(_BaseGrafeasRestTransport._BaseListNotes, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.ListNotes") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__(self, + request: grafeas.ListNotesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> grafeas.ListNotesResponse: + r"""Call the list notes method over HTTP. + + Args: + request (~.grafeas.ListNotesRequest): + The request object. Request to list notes. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.grafeas.ListNotesResponse: + Response for listing notes. + """ + + http_options = _BaseGrafeasRestTransport._BaseListNotes._get_http_options() + request, metadata = self._interceptor.pre_list_notes(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseListNotes._get_transcoded_request(http_options, request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseListNotes._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._ListNotes._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) + + # 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 = grafeas.ListNotesResponse() + pb_resp = grafeas.ListNotesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_notes(resp) + return resp + + class _ListOccurrences(_BaseGrafeasRestTransport._BaseListOccurrences, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.ListOccurrences") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__(self, + request: grafeas.ListOccurrencesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> grafeas.ListOccurrencesResponse: + r"""Call the list occurrences method over HTTP. + + Args: + request (~.grafeas.ListOccurrencesRequest): + The request object. Request to list occurrences. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.grafeas.ListOccurrencesResponse: + Response for listing occurrences. + """ + + http_options = _BaseGrafeasRestTransport._BaseListOccurrences._get_http_options() + request, metadata = self._interceptor.pre_list_occurrences(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseListOccurrences._get_transcoded_request(http_options, request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseListOccurrences._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._ListOccurrences._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) + + # 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 = grafeas.ListOccurrencesResponse() + pb_resp = grafeas.ListOccurrencesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_occurrences(resp) + return resp + + class _UpdateNote(_BaseGrafeasRestTransport._BaseUpdateNote, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.UpdateNote") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__(self, + request: grafeas.UpdateNoteRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> grafeas.Note: + r"""Call the update note method over HTTP. + + Args: + request (~.grafeas.UpdateNoteRequest): + The request object. Request to update a note. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.grafeas.Note: + A type of analysis that can be done + for a resource. + + """ + + http_options = _BaseGrafeasRestTransport._BaseUpdateNote._get_http_options() + request, metadata = self._interceptor.pre_update_note(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseUpdateNote._get_transcoded_request(http_options, request) + + body = _BaseGrafeasRestTransport._BaseUpdateNote._get_request_body_json(transcoded_request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseUpdateNote._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._UpdateNote._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = grafeas.Note() + pb_resp = grafeas.Note.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_note(resp) + return resp + + class _UpdateOccurrence(_BaseGrafeasRestTransport._BaseUpdateOccurrence, GrafeasRestStub): + def __hash__(self): + return hash("GrafeasRestTransport.UpdateOccurrence") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None): + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + headers = dict(metadata) + headers['Content-Type'] = 'application/json' + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__(self, + request: grafeas.UpdateOccurrenceRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> grafeas.Occurrence: + r"""Call the update occurrence method over HTTP. + + Args: + request (~.grafeas.UpdateOccurrenceRequest): + The request object. Request to update an occurrence. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.grafeas.Occurrence: + An instance of an analysis type that + has been found on a resource. + + """ + + http_options = _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_http_options() + request, metadata = self._interceptor.pre_update_occurrence(request, metadata) + transcoded_request = _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_transcoded_request(http_options, request) + + body = _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_request_body_json(transcoded_request) + + # Jsonify the query params + query_params = _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_query_params_json(transcoded_request) + + # Send the request + response = GrafeasRestTransport._UpdateOccurrence._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = grafeas.Occurrence() + pb_resp = grafeas.Occurrence.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_occurrence(resp) + return resp + + @property + def batch_create_notes(self) -> Callable[ + [grafeas.BatchCreateNotesRequest], + grafeas.BatchCreateNotesResponse]: + # 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._BatchCreateNotes(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_create_occurrences(self) -> Callable[ + [grafeas.BatchCreateOccurrencesRequest], + grafeas.BatchCreateOccurrencesResponse]: + # 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._BatchCreateOccurrences(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_note(self) -> Callable[ + [grafeas.CreateNoteRequest], + grafeas.Note]: + # 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._CreateNote(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_occurrence(self) -> Callable[ + [grafeas.CreateOccurrenceRequest], + grafeas.Occurrence]: + # 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._CreateOccurrence(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_note(self) -> Callable[ + [grafeas.DeleteNoteRequest], + 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._DeleteNote(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_occurrence(self) -> Callable[ + [grafeas.DeleteOccurrenceRequest], + 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._DeleteOccurrence(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_note(self) -> Callable[ + [grafeas.GetNoteRequest], + grafeas.Note]: + # 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._GetNote(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_occurrence(self) -> Callable[ + [grafeas.GetOccurrenceRequest], + grafeas.Occurrence]: + # 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._GetOccurrence(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_occurrence_note(self) -> Callable[ + [grafeas.GetOccurrenceNoteRequest], + grafeas.Note]: + # 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._GetOccurrenceNote(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_note_occurrences(self) -> Callable[ + [grafeas.ListNoteOccurrencesRequest], + grafeas.ListNoteOccurrencesResponse]: + # 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._ListNoteOccurrences(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_notes(self) -> Callable[ + [grafeas.ListNotesRequest], + grafeas.ListNotesResponse]: + # 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._ListNotes(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_occurrences(self) -> Callable[ + [grafeas.ListOccurrencesRequest], + grafeas.ListOccurrencesResponse]: + # 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._ListOccurrences(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_note(self) -> Callable[ + [grafeas.UpdateNoteRequest], + grafeas.Note]: + # 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._UpdateNote(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_occurrence(self) -> Callable[ + [grafeas.UpdateOccurrenceRequest], + grafeas.Occurrence]: + # 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._UpdateOccurrence(self._session, self._host, self._interceptor) # type: ignore + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'GrafeasRestTransport', +) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest_base.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest_base.py new file mode 100644 index 000000000000..64f998e72c3e --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest_base.py @@ -0,0 +1,732 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 json # type: ignore +from google.api_core import path_template +from google.api_core import gapic_v1 + +from google.protobuf import json_format +from .base import GrafeasTransport, DEFAULT_CLIENT_INFO + +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + + +from google.protobuf import empty_pb2 # type: ignore +from grafeas.grafeas_v1.types import grafeas + + +class _BaseGrafeasRestTransport(GrafeasTransport): + """Base REST backend transport for Grafeas. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + 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 = 'containeranalysis.googleapis.com', + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = 'https', + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'containeranalysis.googleapis.com'). + credentials (Optional[Any]): 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. + 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 + 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 + ) + + class _BaseBatchCreateNotes: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*}/notes:batchCreate', + 'body': '*', + }, + { + 'method': 'post', + 'uri': '/v1/{parent=projects/*/locations/*}/notes:batchCreate', + 'body': '*', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.BatchCreateNotesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + use_integers_for_enums=True + ) + return body + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseBatchCreateNotes._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchCreateOccurrences: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*}/occurrences:batchCreate', + 'body': '*', + }, + { + 'method': 'post', + 'uri': '/v1/{parent=projects/*/locations/*}/occurrences:batchCreate', + 'body': '*', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.BatchCreateOccurrencesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + use_integers_for_enums=True + ) + return body + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCreateNote: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "noteId" : "", } + + @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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*}/notes', + 'body': 'note', + }, + { + 'method': 'post', + 'uri': '/v1/{parent=projects/*/locations/*}/notes', + 'body': 'note', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.CreateNoteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + use_integers_for_enums=True + ) + return body + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseCreateNote._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCreateOccurrence: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v1/{parent=projects/*}/occurrences', + 'body': 'occurrence', + }, + { + 'method': 'post', + 'uri': '/v1/{parent=projects/*/locations/*}/occurrences', + 'body': 'occurrence', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.CreateOccurrenceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + use_integers_for_enums=True + ) + return body + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseCreateOccurrence._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteNote: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'delete', + 'uri': '/v1/{name=projects/*/notes/*}', + }, + { + 'method': 'delete', + 'uri': '/v1/{name=projects/*/locations/*/notes/*}', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.DeleteNoteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseDeleteNote._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteOccurrence: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'delete', + 'uri': '/v1/{name=projects/*/occurrences/*}', + }, + { + 'method': 'delete', + 'uri': '/v1/{name=projects/*/locations/*/occurrences/*}', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.DeleteOccurrenceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseDeleteOccurrence._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetNote: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1/{name=projects/*/notes/*}', + }, + { + 'method': 'get', + 'uri': '/v1/{name=projects/*/locations/*/notes/*}', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.GetNoteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseGetNote._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOccurrence: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1/{name=projects/*/occurrences/*}', + }, + { + 'method': 'get', + 'uri': '/v1/{name=projects/*/locations/*/occurrences/*}', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.GetOccurrenceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseGetOccurrence._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOccurrenceNote: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1/{name=projects/*/occurrences/*}/notes', + }, + { + 'method': 'get', + 'uri': '/v1/{name=projects/*/locations/*/occurrences/*}/notes', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.GetOccurrenceNoteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseGetOccurrenceNote._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListNoteOccurrences: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1/{name=projects/*/notes/*}/occurrences', + }, + { + 'method': 'get', + 'uri': '/v1/{name=projects/*/locations/*/notes/*}/occurrences', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.ListNoteOccurrencesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseListNoteOccurrences._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListNotes: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1/{parent=projects/*}/notes', + }, + { + 'method': 'get', + 'uri': '/v1/{parent=projects/*/locations/*}/notes', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.ListNotesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseListNotes._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListOccurrences: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v1/{parent=projects/*}/occurrences', + }, + { + 'method': 'get', + 'uri': '/v1/{parent=projects/*/locations/*}/occurrences', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.ListOccurrencesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseListOccurrences._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateNote: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v1/{name=projects/*/notes/*}', + 'body': 'note', + }, + { + 'method': 'patch', + 'uri': '/v1/{name=projects/*/locations/*/notes/*}', + 'body': 'note', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.UpdateNoteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + use_integers_for_enums=True + ) + return body + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseUpdateNote._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateOccurrence: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __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} + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v1/{name=projects/*/occurrences/*}', + 'body': 'occurrence', + }, + { + 'method': 'patch', + 'uri': '/v1/{name=projects/*/locations/*/occurrences/*}', + 'body': 'occurrence', + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = grafeas.UpdateOccurrenceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request['body'], + use_integers_for_enums=True + ) + return body + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json_format.MessageToJson( + transcoded_request['query_params'], + use_integers_for_enums=True, + )) + query_params.update(_BaseGrafeasRestTransport._BaseUpdateOccurrence._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + +__all__=( + '_BaseGrafeasRestTransport', +) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/__init__.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/__init__.py new file mode 100644 index 000000000000..76e667190447 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/__init__.py @@ -0,0 +1,244 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .attestation import ( + AttestationNote, + AttestationOccurrence, + Jwt, +) +from .build import ( + BuildNote, + BuildOccurrence, +) +from .common import ( + Digest, + Envelope, + EnvelopeSignature, + FileLocation, + License, + RelatedUrl, + Signature, + NoteKind, +) +from .compliance import ( + ComplianceNote, + ComplianceOccurrence, + ComplianceVersion, + NonCompliantFile, +) +from .cvss import ( + CVSS, + CVSSv3, + CVSSVersion, +) +from .deployment import ( + DeploymentNote, + DeploymentOccurrence, +) +from .discovery import ( + DiscoveryNote, + DiscoveryOccurrence, +) +from .dsse_attestation import ( + DSSEAttestationNote, + DSSEAttestationOccurrence, +) +from .grafeas import ( + BatchCreateNotesRequest, + BatchCreateNotesResponse, + BatchCreateOccurrencesRequest, + BatchCreateOccurrencesResponse, + CreateNoteRequest, + CreateOccurrenceRequest, + DeleteNoteRequest, + DeleteOccurrenceRequest, + GetNoteRequest, + GetOccurrenceNoteRequest, + GetOccurrenceRequest, + ListNoteOccurrencesRequest, + ListNoteOccurrencesResponse, + ListNotesRequest, + ListNotesResponse, + ListOccurrencesRequest, + ListOccurrencesResponse, + Note, + Occurrence, + UpdateNoteRequest, + UpdateOccurrenceRequest, +) +from .image import ( + Fingerprint, + ImageNote, + ImageOccurrence, + Layer, +) +from .intoto_provenance import ( + BuilderConfig, + Completeness, + InTotoProvenance, + Metadata, + Recipe, +) +from .intoto_statement import ( + InTotoSlsaProvenanceV1, + InTotoStatement, + Subject, +) +from .package import ( + Distribution, + Location, + PackageNote, + PackageOccurrence, + Version, + Architecture, +) +from .provenance import ( + AliasContext, + Artifact, + BuildProvenance, + CloudRepoSourceContext, + Command, + FileHashes, + GerritSourceContext, + GitSourceContext, + Hash, + ProjectRepoId, + RepoId, + Source, + SourceContext, +) +from .sbom import ( + SbomReferenceIntotoPayload, + SbomReferenceIntotoPredicate, + SBOMReferenceNote, + SBOMReferenceOccurrence, +) +from .severity import ( + Severity, +) +from .slsa_provenance import ( + SlsaProvenance, +) +from .slsa_provenance_zero_two import ( + SlsaProvenanceZeroTwo, +) +from .upgrade import ( + UpgradeDistribution, + UpgradeNote, + UpgradeOccurrence, + WindowsUpdate, +) +from .vex import ( + VulnerabilityAssessmentNote, +) +from .vulnerability import ( + VulnerabilityNote, + VulnerabilityOccurrence, +) + +__all__ = ( + 'AttestationNote', + 'AttestationOccurrence', + 'Jwt', + 'BuildNote', + 'BuildOccurrence', + 'Digest', + 'Envelope', + 'EnvelopeSignature', + 'FileLocation', + 'License', + 'RelatedUrl', + 'Signature', + 'NoteKind', + 'ComplianceNote', + 'ComplianceOccurrence', + 'ComplianceVersion', + 'NonCompliantFile', + 'CVSS', + 'CVSSv3', + 'CVSSVersion', + 'DeploymentNote', + 'DeploymentOccurrence', + 'DiscoveryNote', + 'DiscoveryOccurrence', + 'DSSEAttestationNote', + 'DSSEAttestationOccurrence', + 'BatchCreateNotesRequest', + 'BatchCreateNotesResponse', + 'BatchCreateOccurrencesRequest', + 'BatchCreateOccurrencesResponse', + 'CreateNoteRequest', + 'CreateOccurrenceRequest', + 'DeleteNoteRequest', + 'DeleteOccurrenceRequest', + 'GetNoteRequest', + 'GetOccurrenceNoteRequest', + 'GetOccurrenceRequest', + 'ListNoteOccurrencesRequest', + 'ListNoteOccurrencesResponse', + 'ListNotesRequest', + 'ListNotesResponse', + 'ListOccurrencesRequest', + 'ListOccurrencesResponse', + 'Note', + 'Occurrence', + 'UpdateNoteRequest', + 'UpdateOccurrenceRequest', + 'Fingerprint', + 'ImageNote', + 'ImageOccurrence', + 'Layer', + 'BuilderConfig', + 'Completeness', + 'InTotoProvenance', + 'Metadata', + 'Recipe', + 'InTotoSlsaProvenanceV1', + 'InTotoStatement', + 'Subject', + 'Distribution', + 'Location', + 'PackageNote', + 'PackageOccurrence', + 'Version', + 'Architecture', + 'AliasContext', + 'Artifact', + 'BuildProvenance', + 'CloudRepoSourceContext', + 'Command', + 'FileHashes', + 'GerritSourceContext', + 'GitSourceContext', + 'Hash', + 'ProjectRepoId', + 'RepoId', + 'Source', + 'SourceContext', + 'SbomReferenceIntotoPayload', + 'SbomReferenceIntotoPredicate', + 'SBOMReferenceNote', + 'SBOMReferenceOccurrence', + 'Severity', + 'SlsaProvenance', + 'SlsaProvenanceZeroTwo', + 'UpgradeDistribution', + 'UpgradeNote', + 'UpgradeOccurrence', + 'WindowsUpdate', + 'VulnerabilityAssessmentNote', + 'VulnerabilityNote', + 'VulnerabilityOccurrence', +) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/attestation.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/attestation.py new file mode 100644 index 000000000000..b001a8ec82a7 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/attestation.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import common + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'AttestationNote', + 'Jwt', + 'AttestationOccurrence', + }, +) + + +class AttestationNote(proto.Message): + r"""Note kind that represents a logical attestation "role" or + "authority". For example, an organization might have one + ``Authority`` for "QA" and one for "build". This note is intended to + act strictly as a grouping mechanism for the attached occurrences + (Attestations). This grouping mechanism also provides a security + boundary, since IAM ACLs gate the ability for a principle to attach + an occurrence to a given note. It also provides a single point of + lookup to find all attached attestation occurrences, even if they + don't all live in the same project. + + Attributes: + hint (grafeas.grafeas_v1.types.AttestationNote.Hint): + Hint hints at the purpose of the attestation + authority. + """ + + class Hint(proto.Message): + r"""This submessage provides human-readable hints about the + purpose of the authority. Because the name of a note acts as its + resource reference, it is important to disambiguate the + canonical name of the Note (which might be a UUID for security + purposes) from "readable" names more suitable for debug output. + Note that these hints should not be used to look up authorities + in security sensitive contexts, such as when looking up + attestations to verify. + + Attributes: + human_readable_name (str): + Required. The human readable name of this + attestation authority, for example "qa". + """ + + human_readable_name: str = proto.Field( + proto.STRING, + number=1, + ) + + hint: Hint = proto.Field( + proto.MESSAGE, + number=1, + message=Hint, + ) + + +class Jwt(proto.Message): + r""" + + Attributes: + compact_jwt (str): + The compact encoding of a JWS, which is + always three base64 encoded strings joined by + periods. For details, see: + + https://tools.ietf.org/html/rfc7515.html#section-3.1 + """ + + compact_jwt: str = proto.Field( + proto.STRING, + number=1, + ) + + +class AttestationOccurrence(proto.Message): + r"""Occurrence that represents a single "attestation". The + authenticity of an attestation can be verified using the + attached signature. If the verifier trusts the public key of the + signer, then verifying the signature is sufficient to establish + trust. In this circumstance, the authority to which this + attestation is attached is primarily useful for lookup (how to + find this attestation if you already know the authority and + artifact to be verified) and intent (for which authority this + attestation was intended to sign. + + Attributes: + serialized_payload (bytes): + Required. The serialized payload that is verified by one or + more ``signatures``. + signatures (MutableSequence[grafeas.grafeas_v1.types.Signature]): + One or more signatures over ``serialized_payload``. Verifier + implementations should consider this attestation message + verified if at least one ``signature`` verifies + ``serialized_payload``. See ``Signature`` in common.proto + for more details on signature structure and verification. + jwts (MutableSequence[grafeas.grafeas_v1.types.Jwt]): + One or more JWTs encoding a self-contained attestation. Each + JWT encodes the payload that it verifies within the JWT + itself. Verifier implementation SHOULD ignore the + ``serialized_payload`` field when verifying these JWTs. If + only JWTs are present on this AttestationOccurrence, then + the ``serialized_payload`` SHOULD be left empty. Each JWT + SHOULD encode a claim specific to the ``resource_uri`` of + this Occurrence, but this is not validated by Grafeas + metadata API implementations. The JWT itself is opaque to + Grafeas. + """ + + serialized_payload: bytes = proto.Field( + proto.BYTES, + number=1, + ) + signatures: MutableSequence[common.Signature] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=common.Signature, + ) + jwts: MutableSequence['Jwt'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Jwt', + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/build.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/build.py new file mode 100644 index 000000000000..10eea8a73894 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/build.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import intoto_provenance as g_intoto_provenance +from grafeas.grafeas_v1.types import intoto_statement as g_intoto_statement +from grafeas.grafeas_v1.types import provenance as g_provenance + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'BuildNote', + 'BuildOccurrence', + }, +) + + +class BuildNote(proto.Message): + r"""Note holding the version of the provider's builder and the + signature of the provenance message in the build details + occurrence. + + Attributes: + builder_version (str): + Required. Immutable. Version of the builder + which produced this build. + """ + + builder_version: str = proto.Field( + proto.STRING, + number=1, + ) + + +class BuildOccurrence(proto.Message): + r"""Details of a build occurrence. + + Attributes: + provenance (grafeas.grafeas_v1.types.BuildProvenance): + The actual provenance for the build. + provenance_bytes (str): + Serialized JSON representation of the provenance, used in + generating the build signature in the corresponding build + note. After verifying the signature, ``provenance_bytes`` + can be unmarshalled and compared to the provenance to + confirm that it is unchanged. A base64-encoded string + representation of the provenance bytes is used for the + signature in order to interoperate with openssl which + expects this format for signature verification. + + The serialized form is captured both to avoid ambiguity in + how the provenance is marshalled to json as well to prevent + incompatibilities with future changes. + intoto_provenance (grafeas.grafeas_v1.types.InTotoProvenance): + Deprecated. See InTotoStatement for the + replacement. In-toto Provenance representation + as defined in spec. + intoto_statement (grafeas.grafeas_v1.types.InTotoStatement): + In-toto Statement representation as defined in spec. The + intoto_statement can contain any type of provenance. The + serialized payload of the statement can be stored and signed + in the Occurrence's envelope. + in_toto_slsa_provenance_v1 (grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1): + In-Toto Slsa Provenance V1 represents a slsa + provenance meeting the slsa spec, wrapped in an + in-toto statement. This allows for direct + jsonification of a to-spec in-toto slsa + statement with a to-spec slsa provenance. + """ + + provenance: g_provenance.BuildProvenance = proto.Field( + proto.MESSAGE, + number=1, + message=g_provenance.BuildProvenance, + ) + provenance_bytes: str = proto.Field( + proto.STRING, + number=2, + ) + intoto_provenance: g_intoto_provenance.InTotoProvenance = proto.Field( + proto.MESSAGE, + number=3, + message=g_intoto_provenance.InTotoProvenance, + ) + intoto_statement: g_intoto_statement.InTotoStatement = proto.Field( + proto.MESSAGE, + number=4, + message=g_intoto_statement.InTotoStatement, + ) + in_toto_slsa_provenance_v1: g_intoto_statement.InTotoSlsaProvenanceV1 = proto.Field( + proto.MESSAGE, + number=5, + message=g_intoto_statement.InTotoSlsaProvenanceV1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/common.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/common.py new file mode 100644 index 000000000000..047f564874ba --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/common.py @@ -0,0 +1,295 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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='grafeas.v1', + manifest={ + 'NoteKind', + 'RelatedUrl', + 'Signature', + 'Envelope', + 'EnvelopeSignature', + 'FileLocation', + 'License', + 'Digest', + }, +) + + +class NoteKind(proto.Enum): + r"""Kind represents the kinds of notes supported. + + Values: + NOTE_KIND_UNSPECIFIED (0): + Default value. This value is unused. + VULNERABILITY (1): + The note and occurrence represent a package + vulnerability. + BUILD (2): + The note and occurrence assert build + provenance. + IMAGE (3): + This represents an image basis relationship. + PACKAGE (4): + This represents a package installed via a + package manager. + DEPLOYMENT (5): + The note and occurrence track deployment + events. + DISCOVERY (6): + The note and occurrence track the initial + discovery status of a resource. + ATTESTATION (7): + This represents a logical "role" that can + attest to artifacts. + UPGRADE (8): + This represents an available package upgrade. + COMPLIANCE (9): + This represents a Compliance Note + DSSE_ATTESTATION (10): + This represents a DSSE attestation Note + VULNERABILITY_ASSESSMENT (11): + This represents a Vulnerability Assessment. + SBOM_REFERENCE (12): + This represents an SBOM Reference. + """ + NOTE_KIND_UNSPECIFIED = 0 + VULNERABILITY = 1 + BUILD = 2 + IMAGE = 3 + PACKAGE = 4 + DEPLOYMENT = 5 + DISCOVERY = 6 + ATTESTATION = 7 + UPGRADE = 8 + COMPLIANCE = 9 + DSSE_ATTESTATION = 10 + VULNERABILITY_ASSESSMENT = 11 + SBOM_REFERENCE = 12 + + +class RelatedUrl(proto.Message): + r"""Metadata for any related URL information. + + Attributes: + url (str): + Specific URL associated with the resource. + label (str): + Label to describe usage of the URL. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + label: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Signature(proto.Message): + r"""Verifiers (e.g. Kritis implementations) MUST verify signatures with + respect to the trust anchors defined in policy (e.g. a Kritis + policy). Typically this means that the verifier has been configured + with a map from ``public_key_id`` to public key material (and any + required parameters, e.g. signing algorithm). + + In particular, verification implementations MUST NOT treat the + signature ``public_key_id`` as anything more than a key lookup hint. + The ``public_key_id`` DOES NOT validate or authenticate a public + key; it only provides a mechanism for quickly selecting a public key + ALREADY CONFIGURED on the verifier through a trusted channel. + Verification implementations MUST reject signatures in any of the + following circumstances: + + - The ``public_key_id`` is not recognized by the verifier. + - The public key that ``public_key_id`` refers to does not verify + the signature with respect to the payload. + + The ``signature`` contents SHOULD NOT be "attached" (where the + payload is included with the serialized ``signature`` bytes). + Verifiers MUST ignore any "attached" payload and only verify + signatures with respect to explicitly provided payload (e.g. a + ``payload`` field on the proto message that holds this Signature, or + the canonical serialization of the proto message that holds this + signature). + + Attributes: + signature (bytes): + The content of the signature, an opaque + bytestring. The payload that this signature + verifies MUST be unambiguously provided with the + Signature during verification. A wrapper message + might provide the payload explicitly. + Alternatively, a message might have a canonical + serialization that can always be unambiguously + computed to derive the payload. + public_key_id (str): + The identifier for the public key that verifies this + signature. + + - The ``public_key_id`` is required. + - The ``public_key_id`` SHOULD be an RFC3986 conformant + URI. + - When possible, the ``public_key_id`` SHOULD be an + immutable reference, such as a cryptographic digest. + + Examples of valid ``public_key_id``\ s: + + OpenPGP V4 public key fingerprint: + + - "openpgp4fpr:74FAF3B861BDA0870C7B6DEF607E48D2A663AEEA" + See + https://www.iana.org/assignments/uri-schemes/prov/openpgp4fpr + for more details on this scheme. + + RFC6920 digest-named SubjectPublicKeyInfo (digest of the DER + serialization): + + - "ni:///sha-256;cD9o9Cq6LG3jD0iKXqEi_vdjJGecm_iXkbqVoScViaU" + - "nih:///sha-256;703f68f42aba2c6de30f488a5ea122fef76324679c9bf89791ba95a1271589a5". + """ + + signature: bytes = proto.Field( + proto.BYTES, + number=1, + ) + public_key_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Envelope(proto.Message): + r"""MUST match + https://github.com/secure-systems-lab/dsse/blob/master/envelope.proto. + An authenticated message of arbitrary type. + + Attributes: + payload (bytes): + + payload_type (str): + + signatures (MutableSequence[grafeas.grafeas_v1.types.EnvelopeSignature]): + + """ + + payload: bytes = proto.Field( + proto.BYTES, + number=1, + ) + payload_type: str = proto.Field( + proto.STRING, + number=2, + ) + signatures: MutableSequence['EnvelopeSignature'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='EnvelopeSignature', + ) + + +class EnvelopeSignature(proto.Message): + r""" + + Attributes: + sig (bytes): + + keyid (str): + + """ + + sig: bytes = proto.Field( + proto.BYTES, + number=1, + ) + keyid: str = proto.Field( + proto.STRING, + number=2, + ) + + +class FileLocation(proto.Message): + r"""Indicates the location at which a package was found. + + Attributes: + file_path (str): + For jars that are contained inside .war + files, this filepath can indicate the path to + war file combined with the path to jar file. + """ + + file_path: str = proto.Field( + proto.STRING, + number=1, + ) + + +class License(proto.Message): + r"""License information. + + Attributes: + expression (str): + Often a single license can be used to + represent the licensing terms. Sometimes it is + necessary to include a choice of one or more + licenses or some combination of license + identifiers. + Examples: "LGPL-2.1-only OR MIT", "LGPL-2.1-only + AND MIT", "GPL-2.0-or-later WITH + Bison-exception-2.2". + comments (str): + Comments + """ + + expression: str = proto.Field( + proto.STRING, + number=1, + ) + comments: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Digest(proto.Message): + r"""Digest information. + + Attributes: + algo (str): + ``SHA1``, ``SHA512`` etc. + digest_bytes (bytes): + Value of the digest. + """ + + algo: str = proto.Field( + proto.STRING, + number=1, + ) + digest_bytes: bytes = proto.Field( + proto.BYTES, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/compliance.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/compliance.py new file mode 100644 index 000000000000..b770fe9748cc --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/compliance.py @@ -0,0 +1,215 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import severity as g_severity + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'ComplianceNote', + 'ComplianceVersion', + 'ComplianceOccurrence', + 'NonCompliantFile', + }, +) + + +class ComplianceNote(proto.Message): + r""" + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + title (str): + The title that identifies this compliance + check. + description (str): + A description about this compliance check. + version (MutableSequence[grafeas.grafeas_v1.types.ComplianceVersion]): + The OS and config versions the benchmark + applies to. + rationale (str): + A rationale for the existence of this + compliance check. + remediation (str): + A description of remediation steps if the + compliance check fails. + cis_benchmark (grafeas.grafeas_v1.types.ComplianceNote.CisBenchmark): + + This field is a member of `oneof`_ ``compliance_type``. + scan_instructions (bytes): + Serialized scan instructions with a + predefined format. + impact (str): + + This field is a member of `oneof`_ ``potential_impact``. + """ + + class CisBenchmark(proto.Message): + r"""A compliance check that is a CIS benchmark. + + Attributes: + profile_level (int): + + severity (grafeas.grafeas_v1.types.Severity): + + """ + + profile_level: int = proto.Field( + proto.INT32, + number=1, + ) + severity: g_severity.Severity = proto.Field( + proto.ENUM, + number=2, + enum=g_severity.Severity, + ) + + title: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + version: MutableSequence['ComplianceVersion'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='ComplianceVersion', + ) + rationale: str = proto.Field( + proto.STRING, + number=4, + ) + remediation: str = proto.Field( + proto.STRING, + number=5, + ) + cis_benchmark: CisBenchmark = proto.Field( + proto.MESSAGE, + number=6, + oneof='compliance_type', + message=CisBenchmark, + ) + scan_instructions: bytes = proto.Field( + proto.BYTES, + number=7, + ) + impact: str = proto.Field( + proto.STRING, + number=8, + oneof='potential_impact', + ) + + +class ComplianceVersion(proto.Message): + r"""Describes the CIS benchmark version that is applicable to a + given OS and os version. + + Attributes: + cpe_uri (str): + The CPE URI + (https://cpe.mitre.org/specification/) this + benchmark is applicable to. + benchmark_document (str): + The name of the document that defines this + benchmark, e.g. "CIS Container-Optimized OS". + version (str): + The version of the benchmark. This is set to + the version of the OS-specific CIS document the + benchmark is defined in. + """ + + cpe_uri: str = proto.Field( + proto.STRING, + number=1, + ) + benchmark_document: str = proto.Field( + proto.STRING, + number=3, + ) + version: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ComplianceOccurrence(proto.Message): + r"""An indication that the compliance checks in the associated + ComplianceNote were not satisfied for particular resources or a + specified reason. + + Attributes: + non_compliant_files (MutableSequence[grafeas.grafeas_v1.types.NonCompliantFile]): + + non_compliance_reason (str): + + version (grafeas.grafeas_v1.types.ComplianceVersion): + The OS and config version the benchmark was + run on. + """ + + non_compliant_files: MutableSequence['NonCompliantFile'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='NonCompliantFile', + ) + non_compliance_reason: str = proto.Field( + proto.STRING, + number=3, + ) + version: 'ComplianceVersion' = proto.Field( + proto.MESSAGE, + number=4, + message='ComplianceVersion', + ) + + +class NonCompliantFile(proto.Message): + r"""Details about files that caused a compliance check to fail. + + Attributes: + path (str): + Empty if ``display_command`` is set. + display_command (str): + Command to display the non-compliant files. + reason (str): + Explains why a file is non compliant for a + CIS check. + """ + + path: str = proto.Field( + proto.STRING, + number=1, + ) + display_command: str = proto.Field( + proto.STRING, + number=2, + ) + reason: str = proto.Field( + proto.STRING, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/cvss.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/cvss.py new file mode 100644 index 000000000000..e0e252edac00 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/cvss.py @@ -0,0 +1,464 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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='grafeas.v1', + manifest={ + 'CVSSVersion', + 'CVSSv3', + 'CVSS', + }, +) + + +class CVSSVersion(proto.Enum): + r"""CVSS Version. + + Values: + CVSS_VERSION_UNSPECIFIED (0): + No description available. + CVSS_VERSION_2 (1): + No description available. + CVSS_VERSION_3 (2): + No description available. + """ + CVSS_VERSION_UNSPECIFIED = 0 + CVSS_VERSION_2 = 1 + CVSS_VERSION_3 = 2 + + +class CVSSv3(proto.Message): + r"""Common Vulnerability Scoring System version 3. + For details, see + https://www.first.org/cvss/specification-document + + Attributes: + base_score (float): + The base score is a function of the base + metric scores. + exploitability_score (float): + + impact_score (float): + + attack_vector (grafeas.grafeas_v1.types.CVSSv3.AttackVector): + Base Metrics + Represents the intrinsic characteristics of a + vulnerability that are constant over time and + across user environments. + attack_complexity (grafeas.grafeas_v1.types.CVSSv3.AttackComplexity): + + privileges_required (grafeas.grafeas_v1.types.CVSSv3.PrivilegesRequired): + + user_interaction (grafeas.grafeas_v1.types.CVSSv3.UserInteraction): + + scope (grafeas.grafeas_v1.types.CVSSv3.Scope): + + confidentiality_impact (grafeas.grafeas_v1.types.CVSSv3.Impact): + + integrity_impact (grafeas.grafeas_v1.types.CVSSv3.Impact): + + availability_impact (grafeas.grafeas_v1.types.CVSSv3.Impact): + + """ + class AttackVector(proto.Enum): + r""" + + Values: + ATTACK_VECTOR_UNSPECIFIED (0): + No description available. + ATTACK_VECTOR_NETWORK (1): + No description available. + ATTACK_VECTOR_ADJACENT (2): + No description available. + ATTACK_VECTOR_LOCAL (3): + No description available. + ATTACK_VECTOR_PHYSICAL (4): + No description available. + """ + ATTACK_VECTOR_UNSPECIFIED = 0 + ATTACK_VECTOR_NETWORK = 1 + ATTACK_VECTOR_ADJACENT = 2 + ATTACK_VECTOR_LOCAL = 3 + ATTACK_VECTOR_PHYSICAL = 4 + + class AttackComplexity(proto.Enum): + r""" + + Values: + ATTACK_COMPLEXITY_UNSPECIFIED (0): + No description available. + ATTACK_COMPLEXITY_LOW (1): + No description available. + ATTACK_COMPLEXITY_HIGH (2): + No description available. + """ + ATTACK_COMPLEXITY_UNSPECIFIED = 0 + ATTACK_COMPLEXITY_LOW = 1 + ATTACK_COMPLEXITY_HIGH = 2 + + class PrivilegesRequired(proto.Enum): + r""" + + Values: + PRIVILEGES_REQUIRED_UNSPECIFIED (0): + No description available. + PRIVILEGES_REQUIRED_NONE (1): + No description available. + PRIVILEGES_REQUIRED_LOW (2): + No description available. + PRIVILEGES_REQUIRED_HIGH (3): + No description available. + """ + PRIVILEGES_REQUIRED_UNSPECIFIED = 0 + PRIVILEGES_REQUIRED_NONE = 1 + PRIVILEGES_REQUIRED_LOW = 2 + PRIVILEGES_REQUIRED_HIGH = 3 + + class UserInteraction(proto.Enum): + r""" + + Values: + USER_INTERACTION_UNSPECIFIED (0): + No description available. + USER_INTERACTION_NONE (1): + No description available. + USER_INTERACTION_REQUIRED (2): + No description available. + """ + USER_INTERACTION_UNSPECIFIED = 0 + USER_INTERACTION_NONE = 1 + USER_INTERACTION_REQUIRED = 2 + + class Scope(proto.Enum): + r""" + + Values: + SCOPE_UNSPECIFIED (0): + No description available. + SCOPE_UNCHANGED (1): + No description available. + SCOPE_CHANGED (2): + No description available. + """ + SCOPE_UNSPECIFIED = 0 + SCOPE_UNCHANGED = 1 + SCOPE_CHANGED = 2 + + class Impact(proto.Enum): + r""" + + Values: + IMPACT_UNSPECIFIED (0): + No description available. + IMPACT_HIGH (1): + No description available. + IMPACT_LOW (2): + No description available. + IMPACT_NONE (3): + No description available. + """ + IMPACT_UNSPECIFIED = 0 + IMPACT_HIGH = 1 + IMPACT_LOW = 2 + IMPACT_NONE = 3 + + base_score: float = proto.Field( + proto.FLOAT, + number=1, + ) + exploitability_score: float = proto.Field( + proto.FLOAT, + number=2, + ) + impact_score: float = proto.Field( + proto.FLOAT, + number=3, + ) + attack_vector: AttackVector = proto.Field( + proto.ENUM, + number=5, + enum=AttackVector, + ) + attack_complexity: AttackComplexity = proto.Field( + proto.ENUM, + number=6, + enum=AttackComplexity, + ) + privileges_required: PrivilegesRequired = proto.Field( + proto.ENUM, + number=7, + enum=PrivilegesRequired, + ) + user_interaction: UserInteraction = proto.Field( + proto.ENUM, + number=8, + enum=UserInteraction, + ) + scope: Scope = proto.Field( + proto.ENUM, + number=9, + enum=Scope, + ) + confidentiality_impact: Impact = proto.Field( + proto.ENUM, + number=10, + enum=Impact, + ) + integrity_impact: Impact = proto.Field( + proto.ENUM, + number=11, + enum=Impact, + ) + availability_impact: Impact = proto.Field( + proto.ENUM, + number=12, + enum=Impact, + ) + + +class CVSS(proto.Message): + r"""Common Vulnerability Scoring System. + For details, see + https://www.first.org/cvss/specification-document This is a + message we will try to use for storing various versions of CVSS + rather than making a separate proto for storing a specific + version. + + Attributes: + base_score (float): + The base score is a function of the base + metric scores. + exploitability_score (float): + + impact_score (float): + + attack_vector (grafeas.grafeas_v1.types.CVSS.AttackVector): + Base Metrics + Represents the intrinsic characteristics of a + vulnerability that are constant over time and + across user environments. + attack_complexity (grafeas.grafeas_v1.types.CVSS.AttackComplexity): + + authentication (grafeas.grafeas_v1.types.CVSS.Authentication): + + privileges_required (grafeas.grafeas_v1.types.CVSS.PrivilegesRequired): + + user_interaction (grafeas.grafeas_v1.types.CVSS.UserInteraction): + + scope (grafeas.grafeas_v1.types.CVSS.Scope): + + confidentiality_impact (grafeas.grafeas_v1.types.CVSS.Impact): + + integrity_impact (grafeas.grafeas_v1.types.CVSS.Impact): + + availability_impact (grafeas.grafeas_v1.types.CVSS.Impact): + + """ + class AttackVector(proto.Enum): + r""" + + Values: + ATTACK_VECTOR_UNSPECIFIED (0): + No description available. + ATTACK_VECTOR_NETWORK (1): + No description available. + ATTACK_VECTOR_ADJACENT (2): + No description available. + ATTACK_VECTOR_LOCAL (3): + No description available. + ATTACK_VECTOR_PHYSICAL (4): + No description available. + """ + ATTACK_VECTOR_UNSPECIFIED = 0 + ATTACK_VECTOR_NETWORK = 1 + ATTACK_VECTOR_ADJACENT = 2 + ATTACK_VECTOR_LOCAL = 3 + ATTACK_VECTOR_PHYSICAL = 4 + + class AttackComplexity(proto.Enum): + r""" + + Values: + ATTACK_COMPLEXITY_UNSPECIFIED (0): + No description available. + ATTACK_COMPLEXITY_LOW (1): + No description available. + ATTACK_COMPLEXITY_HIGH (2): + No description available. + ATTACK_COMPLEXITY_MEDIUM (3): + No description available. + """ + ATTACK_COMPLEXITY_UNSPECIFIED = 0 + ATTACK_COMPLEXITY_LOW = 1 + ATTACK_COMPLEXITY_HIGH = 2 + ATTACK_COMPLEXITY_MEDIUM = 3 + + class Authentication(proto.Enum): + r""" + + Values: + AUTHENTICATION_UNSPECIFIED (0): + No description available. + AUTHENTICATION_MULTIPLE (1): + No description available. + AUTHENTICATION_SINGLE (2): + No description available. + AUTHENTICATION_NONE (3): + No description available. + """ + AUTHENTICATION_UNSPECIFIED = 0 + AUTHENTICATION_MULTIPLE = 1 + AUTHENTICATION_SINGLE = 2 + AUTHENTICATION_NONE = 3 + + class PrivilegesRequired(proto.Enum): + r""" + + Values: + PRIVILEGES_REQUIRED_UNSPECIFIED (0): + No description available. + PRIVILEGES_REQUIRED_NONE (1): + No description available. + PRIVILEGES_REQUIRED_LOW (2): + No description available. + PRIVILEGES_REQUIRED_HIGH (3): + No description available. + """ + PRIVILEGES_REQUIRED_UNSPECIFIED = 0 + PRIVILEGES_REQUIRED_NONE = 1 + PRIVILEGES_REQUIRED_LOW = 2 + PRIVILEGES_REQUIRED_HIGH = 3 + + class UserInteraction(proto.Enum): + r""" + + Values: + USER_INTERACTION_UNSPECIFIED (0): + No description available. + USER_INTERACTION_NONE (1): + No description available. + USER_INTERACTION_REQUIRED (2): + No description available. + """ + USER_INTERACTION_UNSPECIFIED = 0 + USER_INTERACTION_NONE = 1 + USER_INTERACTION_REQUIRED = 2 + + class Scope(proto.Enum): + r""" + + Values: + SCOPE_UNSPECIFIED (0): + No description available. + SCOPE_UNCHANGED (1): + No description available. + SCOPE_CHANGED (2): + No description available. + """ + SCOPE_UNSPECIFIED = 0 + SCOPE_UNCHANGED = 1 + SCOPE_CHANGED = 2 + + class Impact(proto.Enum): + r""" + + Values: + IMPACT_UNSPECIFIED (0): + No description available. + IMPACT_HIGH (1): + No description available. + IMPACT_LOW (2): + No description available. + IMPACT_NONE (3): + No description available. + IMPACT_PARTIAL (4): + No description available. + IMPACT_COMPLETE (5): + No description available. + """ + IMPACT_UNSPECIFIED = 0 + IMPACT_HIGH = 1 + IMPACT_LOW = 2 + IMPACT_NONE = 3 + IMPACT_PARTIAL = 4 + IMPACT_COMPLETE = 5 + + base_score: float = proto.Field( + proto.FLOAT, + number=1, + ) + exploitability_score: float = proto.Field( + proto.FLOAT, + number=2, + ) + impact_score: float = proto.Field( + proto.FLOAT, + number=3, + ) + attack_vector: AttackVector = proto.Field( + proto.ENUM, + number=4, + enum=AttackVector, + ) + attack_complexity: AttackComplexity = proto.Field( + proto.ENUM, + number=5, + enum=AttackComplexity, + ) + authentication: Authentication = proto.Field( + proto.ENUM, + number=6, + enum=Authentication, + ) + privileges_required: PrivilegesRequired = proto.Field( + proto.ENUM, + number=7, + enum=PrivilegesRequired, + ) + user_interaction: UserInteraction = proto.Field( + proto.ENUM, + number=8, + enum=UserInteraction, + ) + scope: Scope = proto.Field( + proto.ENUM, + number=9, + enum=Scope, + ) + confidentiality_impact: Impact = proto.Field( + proto.ENUM, + number=10, + enum=Impact, + ) + integrity_impact: Impact = proto.Field( + proto.ENUM, + number=11, + enum=Impact, + ) + availability_impact: Impact = proto.Field( + proto.ENUM, + number=12, + enum=Impact, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/deployment.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/deployment.py new file mode 100644 index 000000000000..d22e451c7744 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/deployment.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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='grafeas.v1', + manifest={ + 'DeploymentNote', + 'DeploymentOccurrence', + }, +) + + +class DeploymentNote(proto.Message): + r"""An artifact that can be deployed in some runtime. + + Attributes: + resource_uri (MutableSequence[str]): + Required. Resource URI for the artifact being + deployed. + """ + + resource_uri: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + +class DeploymentOccurrence(proto.Message): + r"""The period during which some deployable was active in a + runtime. + + Attributes: + user_email (str): + Identity of the user that triggered this + deployment. + deploy_time (google.protobuf.timestamp_pb2.Timestamp): + Required. Beginning of the lifetime of this + deployment. + undeploy_time (google.protobuf.timestamp_pb2.Timestamp): + End of the lifetime of this deployment. + config (str): + Configuration used to create this deployment. + address (str): + Address of the runtime element hosting this + deployment. + resource_uri (MutableSequence[str]): + Output only. Resource URI for the artifact + being deployed taken from the deployable field + with the same name. + platform (grafeas.grafeas_v1.types.DeploymentOccurrence.Platform): + Platform hosting this deployment. + """ + class Platform(proto.Enum): + r"""Types of platforms. + + Values: + PLATFORM_UNSPECIFIED (0): + Unknown. + GKE (1): + Google Container Engine. + FLEX (2): + Google App Engine: Flexible Environment. + CUSTOM (3): + Custom user-defined platform. + """ + PLATFORM_UNSPECIFIED = 0 + GKE = 1 + FLEX = 2 + CUSTOM = 3 + + user_email: str = proto.Field( + proto.STRING, + number=1, + ) + deploy_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + undeploy_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + config: str = proto.Field( + proto.STRING, + number=4, + ) + address: str = proto.Field( + proto.STRING, + number=5, + ) + resource_uri: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=6, + ) + platform: Platform = proto.Field( + proto.ENUM, + number=7, + enum=Platform, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/discovery.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/discovery.py new file mode 100644 index 000000000000..627ab994ae06 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/discovery.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 +from grafeas.grafeas_v1.types import common + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'DiscoveryNote', + 'DiscoveryOccurrence', + }, +) + + +class DiscoveryNote(proto.Message): + r"""A note that indicates a type of analysis a provider would perform. + This note exists in a provider's project. A ``Discovery`` occurrence + is created in a consumer's project at the start of analysis. + + Attributes: + analysis_kind (grafeas.grafeas_v1.types.NoteKind): + Required. Immutable. The kind of analysis + that is handled by this discovery. + """ + + analysis_kind: common.NoteKind = proto.Field( + proto.ENUM, + number=1, + enum=common.NoteKind, + ) + + +class DiscoveryOccurrence(proto.Message): + r"""Provides information about the analysis status of a + discovered resource. + + Attributes: + continuous_analysis (grafeas.grafeas_v1.types.DiscoveryOccurrence.ContinuousAnalysis): + Whether the resource is continuously + analyzed. + analysis_status (grafeas.grafeas_v1.types.DiscoveryOccurrence.AnalysisStatus): + The status of discovery for the resource. + analysis_completed (grafeas.grafeas_v1.types.DiscoveryOccurrence.AnalysisCompleted): + + analysis_error (MutableSequence[google.rpc.status_pb2.Status]): + Indicates any errors encountered during + analysis of a resource. There could be 0 or more + of these errors. + analysis_status_error (google.rpc.status_pb2.Status): + When an error is encountered this will + contain a LocalizedMessage under details to show + to the user. The LocalizedMessage is output only + and populated by the API. + cpe (str): + The CPE of the resource being scanned. + last_scan_time (google.protobuf.timestamp_pb2.Timestamp): + The last time this resource was scanned. + archive_time (google.protobuf.timestamp_pb2.Timestamp): + The time occurrences related to this + discovery occurrence were archived. + sbom_status (grafeas.grafeas_v1.types.DiscoveryOccurrence.SBOMStatus): + The status of an SBOM generation. + vulnerability_attestation (grafeas.grafeas_v1.types.DiscoveryOccurrence.VulnerabilityAttestation): + The status of an vulnerability attestation + generation. + """ + class ContinuousAnalysis(proto.Enum): + r"""Whether the resource is continuously analyzed. + + Values: + CONTINUOUS_ANALYSIS_UNSPECIFIED (0): + Unknown. + ACTIVE (1): + The resource is continuously analyzed. + INACTIVE (2): + The resource is ignored for continuous + analysis. + """ + CONTINUOUS_ANALYSIS_UNSPECIFIED = 0 + ACTIVE = 1 + INACTIVE = 2 + + class AnalysisStatus(proto.Enum): + r"""Analysis status for a resource. Currently for initial + analysis only (not updated in continuous analysis). + + Values: + ANALYSIS_STATUS_UNSPECIFIED (0): + Unknown. + PENDING (1): + Resource is known but no action has been + taken yet. + SCANNING (2): + Resource is being analyzed. + FINISHED_SUCCESS (3): + Analysis has finished successfully. + COMPLETE (3): + Analysis has completed. + FINISHED_FAILED (4): + Analysis has finished unsuccessfully, the + analysis itself is in a bad state. + FINISHED_UNSUPPORTED (5): + The resource is known not to be supported. + """ + _pb_options = {'allow_alias': True} + ANALYSIS_STATUS_UNSPECIFIED = 0 + PENDING = 1 + SCANNING = 2 + FINISHED_SUCCESS = 3 + COMPLETE = 3 + FINISHED_FAILED = 4 + FINISHED_UNSUPPORTED = 5 + + class AnalysisCompleted(proto.Message): + r"""Indicates which analysis completed successfully. Multiple + types of analysis can be performed on a single resource. + + Attributes: + analysis_type (MutableSequence[str]): + + """ + + analysis_type: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + class SBOMStatus(proto.Message): + r"""The status of an SBOM generation. + + Attributes: + sbom_state (grafeas.grafeas_v1.types.DiscoveryOccurrence.SBOMStatus.SBOMState): + The progress of the SBOM generation. + error (str): + If there was an error generating an SBOM, + this will indicate what that error was. + """ + class SBOMState(proto.Enum): + r"""An enum indicating the progress of the SBOM generation. + + Values: + SBOM_STATE_UNSPECIFIED (0): + Default unknown state. + PENDING (1): + SBOM scanning is pending. + COMPLETE (2): + SBOM scanning has completed. + """ + SBOM_STATE_UNSPECIFIED = 0 + PENDING = 1 + COMPLETE = 2 + + sbom_state: 'DiscoveryOccurrence.SBOMStatus.SBOMState' = proto.Field( + proto.ENUM, + number=1, + enum='DiscoveryOccurrence.SBOMStatus.SBOMState', + ) + error: str = proto.Field( + proto.STRING, + number=2, + ) + + class VulnerabilityAttestation(proto.Message): + r"""The status of an vulnerability attestation generation. + + Attributes: + last_attempt_time (google.protobuf.timestamp_pb2.Timestamp): + The last time we attempted to generate an + attestation. + state (grafeas.grafeas_v1.types.DiscoveryOccurrence.VulnerabilityAttestation.VulnerabilityAttestationState): + The success/failure state of the latest + attestation attempt. + error (str): + If failure, the error reason for why the + attestation generation failed. + """ + class VulnerabilityAttestationState(proto.Enum): + r"""An enum indicating the state of the attestation generation. + + Values: + VULNERABILITY_ATTESTATION_STATE_UNSPECIFIED (0): + Default unknown state. + SUCCESS (1): + Attestation was successfully generated and + stored. + FAILURE (2): + Attestation was unsuccessfully generated and + stored. + """ + VULNERABILITY_ATTESTATION_STATE_UNSPECIFIED = 0 + SUCCESS = 1 + FAILURE = 2 + + last_attempt_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + state: 'DiscoveryOccurrence.VulnerabilityAttestation.VulnerabilityAttestationState' = proto.Field( + proto.ENUM, + number=2, + enum='DiscoveryOccurrence.VulnerabilityAttestation.VulnerabilityAttestationState', + ) + error: str = proto.Field( + proto.STRING, + number=3, + ) + + continuous_analysis: ContinuousAnalysis = proto.Field( + proto.ENUM, + number=1, + enum=ContinuousAnalysis, + ) + analysis_status: AnalysisStatus = proto.Field( + proto.ENUM, + number=2, + enum=AnalysisStatus, + ) + analysis_completed: AnalysisCompleted = proto.Field( + proto.MESSAGE, + number=7, + message=AnalysisCompleted, + ) + analysis_error: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message=status_pb2.Status, + ) + analysis_status_error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=3, + message=status_pb2.Status, + ) + cpe: str = proto.Field( + proto.STRING, + number=4, + ) + last_scan_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + archive_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + sbom_status: SBOMStatus = proto.Field( + proto.MESSAGE, + number=9, + message=SBOMStatus, + ) + vulnerability_attestation: VulnerabilityAttestation = proto.Field( + proto.MESSAGE, + number=10, + message=VulnerabilityAttestation, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/dsse_attestation.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/dsse_attestation.py new file mode 100644 index 000000000000..afc3dc412306 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/dsse_attestation.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import common +from grafeas.grafeas_v1.types import intoto_statement + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'DSSEAttestationNote', + 'DSSEAttestationOccurrence', + }, +) + + +class DSSEAttestationNote(proto.Message): + r""" + + Attributes: + hint (grafeas.grafeas_v1.types.DSSEAttestationNote.DSSEHint): + DSSEHint hints at the purpose of the + attestation authority. + """ + + class DSSEHint(proto.Message): + r"""This submessage provides human-readable hints about the + purpose of the authority. Because the name of a note acts as its + resource reference, it is important to disambiguate the + canonical name of the Note (which might be a UUID for security + purposes) from "readable" names more suitable for debug output. + Note that these hints should not be used to look up authorities + in security sensitive contexts, such as when looking up + attestations to verify. + + Attributes: + human_readable_name (str): + Required. The human readable name of this + attestation authority, for example + "cloudbuild-prod". + """ + + human_readable_name: str = proto.Field( + proto.STRING, + number=1, + ) + + hint: DSSEHint = proto.Field( + proto.MESSAGE, + number=1, + message=DSSEHint, + ) + + +class DSSEAttestationOccurrence(proto.Message): + r"""Deprecated. Prefer to use a regular Occurrence, and populate + the Envelope at the top level of the Occurrence. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + envelope (grafeas.grafeas_v1.types.Envelope): + If doing something security critical, make + sure to verify the signatures in this metadata. + statement (grafeas.grafeas_v1.types.InTotoStatement): + + This field is a member of `oneof`_ ``decoded_payload``. + """ + + envelope: common.Envelope = proto.Field( + proto.MESSAGE, + number=1, + message=common.Envelope, + ) + statement: intoto_statement.InTotoStatement = proto.Field( + proto.MESSAGE, + number=2, + oneof='decoded_payload', + message=intoto_statement.InTotoStatement, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/grafeas.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/grafeas.py new file mode 100644 index 000000000000..b98b55887b0c --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/grafeas.py @@ -0,0 +1,921 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from grafeas.grafeas_v1.types import attestation as g_attestation +from grafeas.grafeas_v1.types import build as g_build +from grafeas.grafeas_v1.types import common +from grafeas.grafeas_v1.types import compliance as g_compliance +from grafeas.grafeas_v1.types import deployment as g_deployment +from grafeas.grafeas_v1.types import discovery as g_discovery +from grafeas.grafeas_v1.types import dsse_attestation as g_dsse_attestation +from grafeas.grafeas_v1.types import image as g_image +from grafeas.grafeas_v1.types import package as g_package +from grafeas.grafeas_v1.types import sbom +from grafeas.grafeas_v1.types import upgrade as g_upgrade +from grafeas.grafeas_v1.types import vex +from grafeas.grafeas_v1.types import vulnerability as g_vulnerability + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'Occurrence', + 'Note', + 'GetOccurrenceRequest', + 'ListOccurrencesRequest', + 'ListOccurrencesResponse', + 'DeleteOccurrenceRequest', + 'CreateOccurrenceRequest', + 'UpdateOccurrenceRequest', + 'GetNoteRequest', + 'GetOccurrenceNoteRequest', + 'ListNotesRequest', + 'ListNotesResponse', + 'DeleteNoteRequest', + 'CreateNoteRequest', + 'UpdateNoteRequest', + 'ListNoteOccurrencesRequest', + 'ListNoteOccurrencesResponse', + 'BatchCreateNotesRequest', + 'BatchCreateNotesResponse', + 'BatchCreateOccurrencesRequest', + 'BatchCreateOccurrencesResponse', + }, +) + + +class Occurrence(proto.Message): + r"""An instance of an analysis type that has been found on a + resource. + + 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: + name (str): + Output only. The name of the occurrence in the form of + ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. + resource_uri (str): + Required. Immutable. A URI that represents the resource for + which the occurrence applies. For example, + ``https://gcr.io/project/image@sha256:123abc`` for a Docker + image. + note_name (str): + Required. Immutable. The analysis note associated with this + occurrence, in the form of + ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. This field can + be used as a filter in list requests. + kind (grafeas.grafeas_v1.types.NoteKind): + Output only. This explicitly denotes which of + the occurrence details are specified. This field + can be used as a filter in list requests. + remediation (str): + A description of actions that can be taken to + remedy the note. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time this occurrence was + created. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time this occurrence was + last updated. + vulnerability (grafeas.grafeas_v1.types.VulnerabilityOccurrence): + Describes a security vulnerability. + + This field is a member of `oneof`_ ``details``. + build (grafeas.grafeas_v1.types.BuildOccurrence): + Describes a verifiable build. + + This field is a member of `oneof`_ ``details``. + image (grafeas.grafeas_v1.types.ImageOccurrence): + Describes how this resource derives from the + basis in the associated note. + + This field is a member of `oneof`_ ``details``. + package (grafeas.grafeas_v1.types.PackageOccurrence): + Describes the installation of a package on + the linked resource. + + This field is a member of `oneof`_ ``details``. + deployment (grafeas.grafeas_v1.types.DeploymentOccurrence): + Describes the deployment of an artifact on a + runtime. + + This field is a member of `oneof`_ ``details``. + discovery (grafeas.grafeas_v1.types.DiscoveryOccurrence): + Describes when a resource was discovered. + + This field is a member of `oneof`_ ``details``. + attestation (grafeas.grafeas_v1.types.AttestationOccurrence): + Describes an attestation of an artifact. + + This field is a member of `oneof`_ ``details``. + upgrade (grafeas.grafeas_v1.types.UpgradeOccurrence): + Describes an available package upgrade on the + linked resource. + + This field is a member of `oneof`_ ``details``. + compliance (grafeas.grafeas_v1.types.ComplianceOccurrence): + Describes a compliance violation on a linked + resource. + + This field is a member of `oneof`_ ``details``. + dsse_attestation (grafeas.grafeas_v1.types.DSSEAttestationOccurrence): + Describes an attestation of an artifact using + dsse. + + This field is a member of `oneof`_ ``details``. + sbom_reference (grafeas.grafeas_v1.types.SBOMReferenceOccurrence): + Describes a specific SBOM reference + occurrences. + + This field is a member of `oneof`_ ``details``. + envelope (grafeas.grafeas_v1.types.Envelope): + https://github.com/secure-systems-lab/dsse + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + resource_uri: str = proto.Field( + proto.STRING, + number=2, + ) + note_name: str = proto.Field( + proto.STRING, + number=3, + ) + kind: common.NoteKind = proto.Field( + proto.ENUM, + number=4, + enum=common.NoteKind, + ) + remediation: str = proto.Field( + proto.STRING, + number=5, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=7, + message=timestamp_pb2.Timestamp, + ) + vulnerability: g_vulnerability.VulnerabilityOccurrence = proto.Field( + proto.MESSAGE, + number=8, + oneof='details', + message=g_vulnerability.VulnerabilityOccurrence, + ) + build: g_build.BuildOccurrence = proto.Field( + proto.MESSAGE, + number=9, + oneof='details', + message=g_build.BuildOccurrence, + ) + image: g_image.ImageOccurrence = proto.Field( + proto.MESSAGE, + number=10, + oneof='details', + message=g_image.ImageOccurrence, + ) + package: g_package.PackageOccurrence = proto.Field( + proto.MESSAGE, + number=11, + oneof='details', + message=g_package.PackageOccurrence, + ) + deployment: g_deployment.DeploymentOccurrence = proto.Field( + proto.MESSAGE, + number=12, + oneof='details', + message=g_deployment.DeploymentOccurrence, + ) + discovery: g_discovery.DiscoveryOccurrence = proto.Field( + proto.MESSAGE, + number=13, + oneof='details', + message=g_discovery.DiscoveryOccurrence, + ) + attestation: g_attestation.AttestationOccurrence = proto.Field( + proto.MESSAGE, + number=14, + oneof='details', + message=g_attestation.AttestationOccurrence, + ) + upgrade: g_upgrade.UpgradeOccurrence = proto.Field( + proto.MESSAGE, + number=15, + oneof='details', + message=g_upgrade.UpgradeOccurrence, + ) + compliance: g_compliance.ComplianceOccurrence = proto.Field( + proto.MESSAGE, + number=16, + oneof='details', + message=g_compliance.ComplianceOccurrence, + ) + dsse_attestation: g_dsse_attestation.DSSEAttestationOccurrence = proto.Field( + proto.MESSAGE, + number=17, + oneof='details', + message=g_dsse_attestation.DSSEAttestationOccurrence, + ) + sbom_reference: sbom.SBOMReferenceOccurrence = proto.Field( + proto.MESSAGE, + number=19, + oneof='details', + message=sbom.SBOMReferenceOccurrence, + ) + envelope: common.Envelope = proto.Field( + proto.MESSAGE, + number=18, + message=common.Envelope, + ) + + +class Note(proto.Message): + r"""A type of analysis that can be done for a resource. + + 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: + name (str): + Output only. The name of the note in the form of + ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. + short_description (str): + A one sentence description of this note. + long_description (str): + A detailed description of this note. + kind (grafeas.grafeas_v1.types.NoteKind): + Output only. The type of analysis. This field + can be used as a filter in list requests. + related_url (MutableSequence[grafeas.grafeas_v1.types.RelatedUrl]): + URLs associated with this note. + expiration_time (google.protobuf.timestamp_pb2.Timestamp): + Time of expiration for this note. Empty if + note does not expire. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time this note was created. + This field can be used as a filter in list + requests. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The time this note was last + updated. This field can be used as a filter in + list requests. + related_note_names (MutableSequence[str]): + Other notes related to this note. + vulnerability (grafeas.grafeas_v1.types.VulnerabilityNote): + A note describing a package vulnerability. + + This field is a member of `oneof`_ ``type``. + build (grafeas.grafeas_v1.types.BuildNote): + A note describing build provenance for a + verifiable build. + + This field is a member of `oneof`_ ``type``. + image (grafeas.grafeas_v1.types.ImageNote): + A note describing a base image. + + This field is a member of `oneof`_ ``type``. + package (grafeas.grafeas_v1.types.PackageNote): + A note describing a package hosted by various + package managers. + + This field is a member of `oneof`_ ``type``. + deployment (grafeas.grafeas_v1.types.DeploymentNote): + A note describing something that can be + deployed. + + This field is a member of `oneof`_ ``type``. + discovery (grafeas.grafeas_v1.types.DiscoveryNote): + A note describing the initial analysis of a + resource. + + This field is a member of `oneof`_ ``type``. + attestation (grafeas.grafeas_v1.types.AttestationNote): + A note describing an attestation role. + + This field is a member of `oneof`_ ``type``. + upgrade (grafeas.grafeas_v1.types.UpgradeNote): + A note describing available package upgrades. + + This field is a member of `oneof`_ ``type``. + compliance (grafeas.grafeas_v1.types.ComplianceNote): + A note describing a compliance check. + + This field is a member of `oneof`_ ``type``. + dsse_attestation (grafeas.grafeas_v1.types.DSSEAttestationNote): + A note describing a dsse attestation note. + + This field is a member of `oneof`_ ``type``. + vulnerability_assessment (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote): + A note describing a vulnerability assessment. + + This field is a member of `oneof`_ ``type``. + sbom_reference (grafeas.grafeas_v1.types.SBOMReferenceNote): + A note describing an SBOM reference. + + This field is a member of `oneof`_ ``type``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + short_description: str = proto.Field( + proto.STRING, + number=2, + ) + long_description: str = proto.Field( + proto.STRING, + number=3, + ) + kind: common.NoteKind = proto.Field( + proto.ENUM, + number=4, + enum=common.NoteKind, + ) + related_url: MutableSequence[common.RelatedUrl] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=common.RelatedUrl, + ) + expiration_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=7, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=8, + message=timestamp_pb2.Timestamp, + ) + related_note_names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + vulnerability: g_vulnerability.VulnerabilityNote = proto.Field( + proto.MESSAGE, + number=10, + oneof='type', + message=g_vulnerability.VulnerabilityNote, + ) + build: g_build.BuildNote = proto.Field( + proto.MESSAGE, + number=11, + oneof='type', + message=g_build.BuildNote, + ) + image: g_image.ImageNote = proto.Field( + proto.MESSAGE, + number=12, + oneof='type', + message=g_image.ImageNote, + ) + package: g_package.PackageNote = proto.Field( + proto.MESSAGE, + number=13, + oneof='type', + message=g_package.PackageNote, + ) + deployment: g_deployment.DeploymentNote = proto.Field( + proto.MESSAGE, + number=14, + oneof='type', + message=g_deployment.DeploymentNote, + ) + discovery: g_discovery.DiscoveryNote = proto.Field( + proto.MESSAGE, + number=15, + oneof='type', + message=g_discovery.DiscoveryNote, + ) + attestation: g_attestation.AttestationNote = proto.Field( + proto.MESSAGE, + number=16, + oneof='type', + message=g_attestation.AttestationNote, + ) + upgrade: g_upgrade.UpgradeNote = proto.Field( + proto.MESSAGE, + number=17, + oneof='type', + message=g_upgrade.UpgradeNote, + ) + compliance: g_compliance.ComplianceNote = proto.Field( + proto.MESSAGE, + number=18, + oneof='type', + message=g_compliance.ComplianceNote, + ) + dsse_attestation: g_dsse_attestation.DSSEAttestationNote = proto.Field( + proto.MESSAGE, + number=19, + oneof='type', + message=g_dsse_attestation.DSSEAttestationNote, + ) + vulnerability_assessment: vex.VulnerabilityAssessmentNote = proto.Field( + proto.MESSAGE, + number=20, + oneof='type', + message=vex.VulnerabilityAssessmentNote, + ) + sbom_reference: sbom.SBOMReferenceNote = proto.Field( + proto.MESSAGE, + number=21, + oneof='type', + message=sbom.SBOMReferenceNote, + ) + + +class GetOccurrenceRequest(proto.Message): + r"""Request to get an occurrence. + + Attributes: + name (str): + The name of the occurrence in the form of + ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListOccurrencesRequest(proto.Message): + r"""Request to list occurrences. + + Attributes: + parent (str): + The name of the project to list occurrences for in the form + of ``projects/[PROJECT_ID]``. + filter (str): + The filter expression. + page_size (int): + Number of occurrences to return in the list. + Must be positive. Max allowed page size is 1000. + If not specified, page size defaults to 20. + page_token (str): + Token to provide to skip to a particular spot + in the list. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + filter: str = proto.Field( + proto.STRING, + number=2, + ) + page_size: int = proto.Field( + proto.INT32, + number=3, + ) + page_token: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ListOccurrencesResponse(proto.Message): + r"""Response for listing occurrences. + + Attributes: + occurrences (MutableSequence[grafeas.grafeas_v1.types.Occurrence]): + The occurrences requested. + next_page_token (str): + The next pagination token in the list response. It should be + used as ``page_token`` for the following request. An empty + value means no more results. + """ + + @property + def raw_page(self): + return self + + occurrences: MutableSequence['Occurrence'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Occurrence', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class DeleteOccurrenceRequest(proto.Message): + r"""Request to delete an occurrence. + + Attributes: + name (str): + The name of the occurrence in the form of + ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateOccurrenceRequest(proto.Message): + r"""Request to create a new occurrence. + + Attributes: + parent (str): + The name of the project in the form of + ``projects/[PROJECT_ID]``, under which the occurrence is to + be created. + occurrence (grafeas.grafeas_v1.types.Occurrence): + The occurrence to create. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + occurrence: 'Occurrence' = proto.Field( + proto.MESSAGE, + number=2, + message='Occurrence', + ) + + +class UpdateOccurrenceRequest(proto.Message): + r"""Request to update an occurrence. + + Attributes: + name (str): + The name of the occurrence in the form of + ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. + occurrence (grafeas.grafeas_v1.types.Occurrence): + The updated occurrence. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The fields to update. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + occurrence: 'Occurrence' = proto.Field( + proto.MESSAGE, + number=2, + message='Occurrence', + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=3, + message=field_mask_pb2.FieldMask, + ) + + +class GetNoteRequest(proto.Message): + r"""Request to get a note. + + Attributes: + name (str): + The name of the note in the form of + ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetOccurrenceNoteRequest(proto.Message): + r"""Request to get the note to which the specified occurrence is + attached. + + Attributes: + name (str): + The name of the occurrence in the form of + ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListNotesRequest(proto.Message): + r"""Request to list notes. + + Attributes: + parent (str): + The name of the project to list notes for in the form of + ``projects/[PROJECT_ID]``. + filter (str): + The filter expression. + page_size (int): + Number of notes to return in the list. Must + be positive. Max allowed page size is 1000. If + not specified, page size defaults to 20. + page_token (str): + Token to provide to skip to a particular spot + in the list. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + filter: str = proto.Field( + proto.STRING, + number=2, + ) + page_size: int = proto.Field( + proto.INT32, + number=3, + ) + page_token: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ListNotesResponse(proto.Message): + r"""Response for listing notes. + + Attributes: + notes (MutableSequence[grafeas.grafeas_v1.types.Note]): + The notes requested. + next_page_token (str): + The next pagination token in the list response. It should be + used as ``page_token`` for the following request. An empty + value means no more results. + """ + + @property + def raw_page(self): + return self + + notes: MutableSequence['Note'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Note', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class DeleteNoteRequest(proto.Message): + r"""Request to delete a note. + + Attributes: + name (str): + The name of the note in the form of + ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateNoteRequest(proto.Message): + r"""Request to create a new note. + + Attributes: + parent (str): + The name of the project in the form of + ``projects/[PROJECT_ID]``, under which the note is to be + created. + note_id (str): + The ID to use for this note. + note (grafeas.grafeas_v1.types.Note): + The note to create. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + note_id: str = proto.Field( + proto.STRING, + number=2, + ) + note: 'Note' = proto.Field( + proto.MESSAGE, + number=3, + message='Note', + ) + + +class UpdateNoteRequest(proto.Message): + r"""Request to update a note. + + Attributes: + name (str): + The name of the note in the form of + ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. + note (grafeas.grafeas_v1.types.Note): + The updated note. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The fields to update. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + note: 'Note' = proto.Field( + proto.MESSAGE, + number=2, + message='Note', + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=3, + message=field_mask_pb2.FieldMask, + ) + + +class ListNoteOccurrencesRequest(proto.Message): + r"""Request to list occurrences for a note. + + Attributes: + name (str): + The name of the note to list occurrences for in the form of + ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. + filter (str): + The filter expression. + page_size (int): + Number of occurrences to return in the list. + page_token (str): + Token to provide to skip to a particular spot + in the list. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + filter: str = proto.Field( + proto.STRING, + number=2, + ) + page_size: int = proto.Field( + proto.INT32, + number=3, + ) + page_token: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ListNoteOccurrencesResponse(proto.Message): + r"""Response for listing occurrences for a note. + + Attributes: + occurrences (MutableSequence[grafeas.grafeas_v1.types.Occurrence]): + The occurrences attached to the specified + note. + next_page_token (str): + Token to provide to skip to a particular spot + in the list. + """ + + @property + def raw_page(self): + return self + + occurrences: MutableSequence['Occurrence'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Occurrence', + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class BatchCreateNotesRequest(proto.Message): + r"""Request to create notes in batch. + + Attributes: + parent (str): + The name of the project in the form of + ``projects/[PROJECT_ID]``, under which the notes are to be + created. + notes (MutableMapping[str, grafeas.grafeas_v1.types.Note]): + The notes to create. Max allowed length is + 1000. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + notes: MutableMapping[str, 'Note'] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=2, + message='Note', + ) + + +class BatchCreateNotesResponse(proto.Message): + r"""Response for creating notes in batch. + + Attributes: + notes (MutableSequence[grafeas.grafeas_v1.types.Note]): + The notes that were created. + """ + + notes: MutableSequence['Note'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Note', + ) + + +class BatchCreateOccurrencesRequest(proto.Message): + r"""Request to create occurrences in batch. + + Attributes: + parent (str): + The name of the project in the form of + ``projects/[PROJECT_ID]``, under which the occurrences are + to be created. + occurrences (MutableSequence[grafeas.grafeas_v1.types.Occurrence]): + The occurrences to create. Max allowed length + is 1000. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + occurrences: MutableSequence['Occurrence'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Occurrence', + ) + + +class BatchCreateOccurrencesResponse(proto.Message): + r"""Response for creating occurrences in batch. + + Attributes: + occurrences (MutableSequence[grafeas.grafeas_v1.types.Occurrence]): + The occurrences that were created. + """ + + occurrences: MutableSequence['Occurrence'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Occurrence', + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/image.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/image.py new file mode 100644 index 000000000000..9fde99b85808 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/image.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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='grafeas.v1', + manifest={ + 'Layer', + 'Fingerprint', + 'ImageNote', + 'ImageOccurrence', + }, +) + + +class Layer(proto.Message): + r"""Layer holds metadata specific to a layer of a Docker image. + + Attributes: + directive (str): + Required. The recovered Dockerfile directive + used to construct this layer. See + https://docs.docker.com/engine/reference/builder/ + for more information. + arguments (str): + The recovered arguments to the Dockerfile + directive. + """ + + directive: str = proto.Field( + proto.STRING, + number=1, + ) + arguments: str = proto.Field( + proto.STRING, + number=2, + ) + + +class Fingerprint(proto.Message): + r"""A set of properties that uniquely identify a given Docker + image. + + Attributes: + v1_name (str): + Required. The layer ID of the final layer in + the Docker image's v1 representation. + v2_blob (MutableSequence[str]): + Required. The ordered list of v2 blobs that + represent a given image. + v2_name (str): + Output only. The name of the image's v2 blobs computed via: + [bottom] := v2_blob[bottom] [N] := sha256(v2_blob[N] + " " + + v2_name[N+1]) Only the name of the final blob is kept. + """ + + v1_name: str = proto.Field( + proto.STRING, + number=1, + ) + v2_blob: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + v2_name: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ImageNote(proto.Message): + r"""Basis describes the base image portion (Note) of the DockerImage + relationship. Linked occurrences are derived from this or an + equivalent image via: FROM Or an equivalent + reference, e.g., a tag of the resource_url. + + Attributes: + resource_url (str): + Required. Immutable. The resource_url for the resource + representing the basis of associated occurrence images. + fingerprint (grafeas.grafeas_v1.types.Fingerprint): + Required. Immutable. The fingerprint of the + base image. + """ + + resource_url: str = proto.Field( + proto.STRING, + number=1, + ) + fingerprint: 'Fingerprint' = proto.Field( + proto.MESSAGE, + number=2, + message='Fingerprint', + ) + + +class ImageOccurrence(proto.Message): + r"""Details of the derived image portion of the DockerImage + relationship. This image would be produced from a Dockerfile + with FROM . + + Attributes: + fingerprint (grafeas.grafeas_v1.types.Fingerprint): + Required. The fingerprint of the derived + image. + distance (int): + Output only. The number of layers by which + this image differs from the associated image + basis. + layer_info (MutableSequence[grafeas.grafeas_v1.types.Layer]): + This contains layer-specific metadata, if populated it has + length "distance" and is ordered with [distance] being the + layer immediately following the base image and [1] being the + final layer. + base_resource_url (str): + Output only. This contains the base image URL + for the derived image occurrence. + """ + + fingerprint: 'Fingerprint' = proto.Field( + proto.MESSAGE, + number=1, + message='Fingerprint', + ) + distance: int = proto.Field( + proto.INT32, + number=2, + ) + layer_info: MutableSequence['Layer'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Layer', + ) + base_resource_url: str = proto.Field( + proto.STRING, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_provenance.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_provenance.py new file mode 100644 index 000000000000..940bd414da8f --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_provenance.py @@ -0,0 +1,248 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 any_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'Recipe', + 'Completeness', + 'Metadata', + 'BuilderConfig', + 'InTotoProvenance', + }, +) + + +class Recipe(proto.Message): + r"""Steps taken to build the artifact. + For a TaskRun, typically each container corresponds to one step + in the recipe. + + Attributes: + type_ (str): + URI indicating what type of recipe was + performed. It determines the meaning of + recipe.entryPoint, recipe.arguments, + recipe.environment, and materials. + defined_in_material (int): + Index in materials containing the recipe + steps that are not implied by recipe.type. For + example, if the recipe type were "make", then + this would point to the source containing the + Makefile, not the make program itself. Set to -1 + if the recipe doesn't come from a material, as + zero is default unset value for int64. + entry_point (str): + String identifying the entry point into the + build. This is often a path to a configuration + file and/or a target label within that file. The + syntax and meaning are defined by recipe.type. + For example, if the recipe type were "make", + then this would reference the directory in which + to run make as well as which target to use. + arguments (MutableSequence[google.protobuf.any_pb2.Any]): + Collection of all external inputs that + influenced the build on top of + recipe.definedInMaterial and recipe.entryPoint. + For example, if the recipe type were "make", + then this might be the flags passed to make + aside from the target, which is captured in + recipe.entryPoint. Since the arguments field can + greatly vary in structure, depending on the + builder and recipe type, this is of form "Any". + environment (MutableSequence[google.protobuf.any_pb2.Any]): + Any other builder-controlled inputs necessary + for correctly evaluating the recipe. Usually + only needed for reproducing the build but not + evaluated as part of policy. Since the + environment field can greatly vary in structure, + depending on the builder and recipe type, this + is of form "Any". + """ + + type_: str = proto.Field( + proto.STRING, + number=1, + ) + defined_in_material: int = proto.Field( + proto.INT64, + number=2, + ) + entry_point: str = proto.Field( + proto.STRING, + number=3, + ) + arguments: MutableSequence[any_pb2.Any] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=any_pb2.Any, + ) + environment: MutableSequence[any_pb2.Any] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=any_pb2.Any, + ) + + +class Completeness(proto.Message): + r"""Indicates that the builder claims certain fields in this + message to be complete. + + Attributes: + arguments (bool): + If true, the builder claims that + recipe.arguments is complete, meaning that all + external inputs are properly captured in the + recipe. + environment (bool): + If true, the builder claims that + recipe.environment is claimed to be complete. + materials (bool): + If true, the builder claims that materials + are complete, usually through some controls to + prevent network access. Sometimes called + "hermetic". + """ + + arguments: bool = proto.Field( + proto.BOOL, + number=1, + ) + environment: bool = proto.Field( + proto.BOOL, + number=2, + ) + materials: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class Metadata(proto.Message): + r"""Other properties of the build. + + Attributes: + build_invocation_id (str): + Identifies the particular build invocation, + which can be useful for finding associated logs + or other ad-hoc analysis. The value SHOULD be + globally unique, per in-toto Provenance spec. + build_started_on (google.protobuf.timestamp_pb2.Timestamp): + The timestamp of when the build started. + build_finished_on (google.protobuf.timestamp_pb2.Timestamp): + The timestamp of when the build completed. + completeness (grafeas.grafeas_v1.types.Completeness): + Indicates that the builder claims certain + fields in this message to be complete. + reproducible (bool): + If true, the builder claims that running the + recipe on materials will produce bit-for-bit + identical output. + """ + + build_invocation_id: str = proto.Field( + proto.STRING, + number=1, + ) + build_started_on: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + build_finished_on: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + completeness: 'Completeness' = proto.Field( + proto.MESSAGE, + number=4, + message='Completeness', + ) + reproducible: bool = proto.Field( + proto.BOOL, + number=5, + ) + + +class BuilderConfig(proto.Message): + r""" + + Attributes: + id (str): + + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + + +class InTotoProvenance(proto.Message): + r""" + + Attributes: + builder_config (grafeas.grafeas_v1.types.BuilderConfig): + required + recipe (grafeas.grafeas_v1.types.Recipe): + Identifies the configuration used for the + build. When combined with materials, this SHOULD + fully describe the build, such that re-running + this recipe results in bit-for-bit identical + output (if the build is reproducible). + metadata (grafeas.grafeas_v1.types.Metadata): + + materials (MutableSequence[str]): + The collection of artifacts that influenced + the build including sources, dependencies, build + tools, base images, and so on. This is + considered to be incomplete unless + metadata.completeness.materials is true. Unset + or null is equivalent to empty. + """ + + builder_config: 'BuilderConfig' = proto.Field( + proto.MESSAGE, + number=1, + message='BuilderConfig', + ) + recipe: 'Recipe' = proto.Field( + proto.MESSAGE, + number=2, + message='Recipe', + ) + metadata: 'Metadata' = proto.Field( + proto.MESSAGE, + number=3, + message='Metadata', + ) + materials: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_statement.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_statement.py new file mode 100644 index 000000000000..d42bddb2cdf9 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_statement.py @@ -0,0 +1,353 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 struct_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from grafeas.grafeas_v1.types import intoto_provenance +from grafeas.grafeas_v1.types import slsa_provenance as g_slsa_provenance +from grafeas.grafeas_v1.types import slsa_provenance_zero_two as g_slsa_provenance_zero_two + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'InTotoStatement', + 'Subject', + 'InTotoSlsaProvenanceV1', + }, +) + + +class InTotoStatement(proto.Message): + r"""Spec defined at + https://github.com/in-toto/attestation/tree/main/spec#statement + The serialized InTotoStatement will be stored as + Envelope.payload. Envelope.payloadType is always + "application/vnd.in-toto+json". + + 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: + type_ (str): + Always ``https://in-toto.io/Statement/v0.1``. + subject (MutableSequence[grafeas.grafeas_v1.types.Subject]): + + predicate_type (str): + ``https://slsa.dev/provenance/v0.1`` for SlsaProvenance. + provenance (grafeas.grafeas_v1.types.InTotoProvenance): + + This field is a member of `oneof`_ ``predicate``. + slsa_provenance (grafeas.grafeas_v1.types.SlsaProvenance): + + This field is a member of `oneof`_ ``predicate``. + slsa_provenance_zero_two (grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo): + + This field is a member of `oneof`_ ``predicate``. + """ + + type_: str = proto.Field( + proto.STRING, + number=1, + ) + subject: MutableSequence['Subject'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Subject', + ) + predicate_type: str = proto.Field( + proto.STRING, + number=3, + ) + provenance: intoto_provenance.InTotoProvenance = proto.Field( + proto.MESSAGE, + number=4, + oneof='predicate', + message=intoto_provenance.InTotoProvenance, + ) + slsa_provenance: g_slsa_provenance.SlsaProvenance = proto.Field( + proto.MESSAGE, + number=5, + oneof='predicate', + message=g_slsa_provenance.SlsaProvenance, + ) + slsa_provenance_zero_two: g_slsa_provenance_zero_two.SlsaProvenanceZeroTwo = proto.Field( + proto.MESSAGE, + number=6, + oneof='predicate', + message=g_slsa_provenance_zero_two.SlsaProvenanceZeroTwo, + ) + + +class Subject(proto.Message): + r""" + + Attributes: + name (str): + + digest (MutableMapping[str, str]): + ``"": ""`` Algorithms can be e.g. + sha256, sha512 See + https://github.com/in-toto/attestation/blob/main/spec/field_types.md#DigestSet + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + digest: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=2, + ) + + +class InTotoSlsaProvenanceV1(proto.Message): + r""" + + Attributes: + type_ (str): + InToto spec defined at + https://github.com/in-toto/attestation/tree/main/spec#statement + subject (MutableSequence[grafeas.grafeas_v1.types.Subject]): + + predicate_type (str): + + predicate (grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.SlsaProvenanceV1): + + """ + + class SlsaProvenanceV1(proto.Message): + r"""Keep in sync with schema at + https://github.com/slsa-framework/slsa/blob/main/docs/provenance/schema/v1/provenance.proto + Builder renamed to ProvenanceBuilder because of Java conflicts. + + Attributes: + build_definition (grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.BuildDefinition): + + run_details (grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.RunDetails): + + """ + + build_definition: 'InTotoSlsaProvenanceV1.BuildDefinition' = proto.Field( + proto.MESSAGE, + number=1, + message='InTotoSlsaProvenanceV1.BuildDefinition', + ) + run_details: 'InTotoSlsaProvenanceV1.RunDetails' = proto.Field( + proto.MESSAGE, + number=2, + message='InTotoSlsaProvenanceV1.RunDetails', + ) + + class BuildDefinition(proto.Message): + r""" + + Attributes: + build_type (str): + + external_parameters (google.protobuf.struct_pb2.Struct): + + internal_parameters (google.protobuf.struct_pb2.Struct): + + resolved_dependencies (MutableSequence[grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.ResourceDescriptor]): + + """ + + build_type: str = proto.Field( + proto.STRING, + number=1, + ) + external_parameters: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=2, + message=struct_pb2.Struct, + ) + internal_parameters: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=3, + message=struct_pb2.Struct, + ) + resolved_dependencies: MutableSequence['InTotoSlsaProvenanceV1.ResourceDescriptor'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='InTotoSlsaProvenanceV1.ResourceDescriptor', + ) + + class ResourceDescriptor(proto.Message): + r""" + + Attributes: + name (str): + + uri (str): + + digest (MutableMapping[str, str]): + + content (bytes): + + download_location (str): + + media_type (str): + + annotations (MutableMapping[str, google.protobuf.struct_pb2.Value]): + + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + uri: str = proto.Field( + proto.STRING, + number=2, + ) + digest: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=3, + ) + content: bytes = proto.Field( + proto.BYTES, + number=4, + ) + download_location: str = proto.Field( + proto.STRING, + number=5, + ) + media_type: str = proto.Field( + proto.STRING, + number=6, + ) + annotations: MutableMapping[str, struct_pb2.Value] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=7, + message=struct_pb2.Value, + ) + + class RunDetails(proto.Message): + r""" + + Attributes: + builder (grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.ProvenanceBuilder): + + metadata (grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.BuildMetadata): + + byproducts (MutableSequence[grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.ResourceDescriptor]): + + """ + + builder: 'InTotoSlsaProvenanceV1.ProvenanceBuilder' = proto.Field( + proto.MESSAGE, + number=1, + message='InTotoSlsaProvenanceV1.ProvenanceBuilder', + ) + metadata: 'InTotoSlsaProvenanceV1.BuildMetadata' = proto.Field( + proto.MESSAGE, + number=2, + message='InTotoSlsaProvenanceV1.BuildMetadata', + ) + byproducts: MutableSequence['InTotoSlsaProvenanceV1.ResourceDescriptor'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='InTotoSlsaProvenanceV1.ResourceDescriptor', + ) + + class ProvenanceBuilder(proto.Message): + r""" + + Attributes: + id (str): + + version (MutableMapping[str, str]): + + builder_dependencies (MutableSequence[grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.ResourceDescriptor]): + + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + version: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=2, + ) + builder_dependencies: MutableSequence['InTotoSlsaProvenanceV1.ResourceDescriptor'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='InTotoSlsaProvenanceV1.ResourceDescriptor', + ) + + class BuildMetadata(proto.Message): + r""" + + Attributes: + invocation_id (str): + + started_on (google.protobuf.timestamp_pb2.Timestamp): + + finished_on (google.protobuf.timestamp_pb2.Timestamp): + + """ + + invocation_id: str = proto.Field( + proto.STRING, + number=1, + ) + started_on: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + finished_on: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + + type_: str = proto.Field( + proto.STRING, + number=1, + ) + subject: MutableSequence['Subject'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Subject', + ) + predicate_type: str = proto.Field( + proto.STRING, + number=3, + ) + predicate: SlsaProvenanceV1 = proto.Field( + proto.MESSAGE, + number=4, + message=SlsaProvenanceV1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/package.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/package.py new file mode 100644 index 000000000000..d2402a958a94 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/package.py @@ -0,0 +1,378 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import common + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'Architecture', + 'Distribution', + 'Location', + 'PackageNote', + 'PackageOccurrence', + 'Version', + }, +) + + +class Architecture(proto.Enum): + r"""Instruction set architectures supported by various package + managers. + + Values: + ARCHITECTURE_UNSPECIFIED (0): + Unknown architecture. + X86 (1): + X86 architecture. + X64 (2): + X64 architecture. + """ + ARCHITECTURE_UNSPECIFIED = 0 + X86 = 1 + X64 = 2 + + +class Distribution(proto.Message): + r"""This represents a particular channel of distribution for a + given package. E.g., Debian's jessie-backports dpkg mirror. + + Attributes: + cpe_uri (str): + The cpe_uri in `CPE + format `__ denoting + the package manager version distributing a package. + architecture (grafeas.grafeas_v1.types.Architecture): + The CPU architecture for which packages in + this distribution channel were built. + latest_version (grafeas.grafeas_v1.types.Version): + The latest available version of this package + in this distribution channel. + maintainer (str): + A freeform string denoting the maintainer of + this package. + url (str): + The distribution channel-specific homepage + for this package. + description (str): + The distribution channel-specific description + of this package. + """ + + cpe_uri: str = proto.Field( + proto.STRING, + number=1, + ) + architecture: 'Architecture' = proto.Field( + proto.ENUM, + number=2, + enum='Architecture', + ) + latest_version: 'Version' = proto.Field( + proto.MESSAGE, + number=3, + message='Version', + ) + maintainer: str = proto.Field( + proto.STRING, + number=4, + ) + url: str = proto.Field( + proto.STRING, + number=5, + ) + description: str = proto.Field( + proto.STRING, + number=6, + ) + + +class Location(proto.Message): + r"""An occurrence of a particular package installation found within a + system's filesystem. E.g., glibc was found in + ``/var/lib/dpkg/status``. + + Attributes: + cpe_uri (str): + Deprecated. The CPE URI in `CPE + format `__ + version (grafeas.grafeas_v1.types.Version): + Deprecated. + The version installed at this location. + path (str): + The path from which we gathered that this + package/version is installed. + """ + + cpe_uri: str = proto.Field( + proto.STRING, + number=1, + ) + version: 'Version' = proto.Field( + proto.MESSAGE, + number=2, + message='Version', + ) + path: str = proto.Field( + proto.STRING, + number=3, + ) + + +class PackageNote(proto.Message): + r"""PackageNote represents a particular package version. + + Attributes: + name (str): + The name of the package. + distribution (MutableSequence[grafeas.grafeas_v1.types.Distribution]): + Deprecated. + The various channels by which a package is + distributed. + package_type (str): + The type of package; whether native or non + native (e.g., ruby gems, node.js packages, + etc.). + cpe_uri (str): + The cpe_uri in `CPE + format `__ denoting + the package manager version distributing a package. The + cpe_uri will be blank for language packages. + architecture (grafeas.grafeas_v1.types.Architecture): + The CPU architecture for which packages in + this distribution channel were built. + Architecture will be blank for language + packages. + version (grafeas.grafeas_v1.types.Version): + The version of the package. + maintainer (str): + A freeform text denoting the maintainer of + this package. + url (str): + The homepage for this package. + description (str): + The description of this package. + license_ (grafeas.grafeas_v1.types.License): + Licenses that have been declared by the + authors of the package. + digest (MutableSequence[grafeas.grafeas_v1.types.Digest]): + Hash value, typically a file digest, that + allows unique identification a specific package. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + distribution: MutableSequence['Distribution'] = proto.RepeatedField( + proto.MESSAGE, + number=10, + message='Distribution', + ) + package_type: str = proto.Field( + proto.STRING, + number=11, + ) + cpe_uri: str = proto.Field( + proto.STRING, + number=12, + ) + architecture: 'Architecture' = proto.Field( + proto.ENUM, + number=13, + enum='Architecture', + ) + version: 'Version' = proto.Field( + proto.MESSAGE, + number=14, + message='Version', + ) + maintainer: str = proto.Field( + proto.STRING, + number=15, + ) + url: str = proto.Field( + proto.STRING, + number=16, + ) + description: str = proto.Field( + proto.STRING, + number=17, + ) + license_: common.License = proto.Field( + proto.MESSAGE, + number=18, + message=common.License, + ) + digest: MutableSequence[common.Digest] = proto.RepeatedField( + proto.MESSAGE, + number=19, + message=common.Digest, + ) + + +class PackageOccurrence(proto.Message): + r"""Details on how a particular software package was installed on + a system. + + Attributes: + name (str): + The name of the installed package. + location (MutableSequence[grafeas.grafeas_v1.types.Location]): + All of the places within the filesystem + versions of this package have been found. + package_type (str): + The type of package; whether native or non + native (e.g., ruby gems, node.js packages, + etc.). + cpe_uri (str): + The cpe_uri in `CPE + format `__ denoting + the package manager version distributing a package. The + cpe_uri will be blank for language packages. + architecture (grafeas.grafeas_v1.types.Architecture): + The CPU architecture for which packages in + this distribution channel were built. + Architecture will be blank for language + packages. + license_ (grafeas.grafeas_v1.types.License): + Licenses that have been declared by the + authors of the package. + version (grafeas.grafeas_v1.types.Version): + The version of the package. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + location: MutableSequence['Location'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Location', + ) + package_type: str = proto.Field( + proto.STRING, + number=3, + ) + cpe_uri: str = proto.Field( + proto.STRING, + number=4, + ) + architecture: 'Architecture' = proto.Field( + proto.ENUM, + number=5, + enum='Architecture', + ) + license_: common.License = proto.Field( + proto.MESSAGE, + number=6, + message=common.License, + ) + version: 'Version' = proto.Field( + proto.MESSAGE, + number=7, + message='Version', + ) + + +class Version(proto.Message): + r"""Version contains structured information about the version of + a package. + + Attributes: + epoch (int): + Used to correct mistakes in the version + numbering scheme. + name (str): + Required only when version kind is NORMAL. + The main part of the version name. + revision (str): + The iteration of the package build from the + above version. + inclusive (bool): + Whether this version is specifying part of an + inclusive range. Grafeas does not have the + capability to specify version ranges; instead we + have fields that specify start version and end + versions. At times this is insufficient - we + also need to specify whether the version is + included in the range or is excluded from the + range. This boolean is expected to be set to + true when the version is included in a range. + kind (grafeas.grafeas_v1.types.Version.VersionKind): + Required. Distinguishes between sentinel + MIN/MAX versions and normal versions. + full_name (str): + Human readable version string. This string is + of the form :- and is + only set when kind is NORMAL. + """ + class VersionKind(proto.Enum): + r"""Whether this is an ordinary package version or a sentinel + MIN/MAX version. + + Values: + VERSION_KIND_UNSPECIFIED (0): + Unknown. + NORMAL (1): + A standard package version. + MINIMUM (2): + A special version representing negative + infinity. + MAXIMUM (3): + A special version representing positive + infinity. + """ + VERSION_KIND_UNSPECIFIED = 0 + NORMAL = 1 + MINIMUM = 2 + MAXIMUM = 3 + + epoch: int = proto.Field( + proto.INT32, + number=1, + ) + name: str = proto.Field( + proto.STRING, + number=2, + ) + revision: str = proto.Field( + proto.STRING, + number=3, + ) + inclusive: bool = proto.Field( + proto.BOOL, + number=6, + ) + kind: VersionKind = proto.Field( + proto.ENUM, + number=4, + enum=VersionKind, + ) + full_name: str = proto.Field( + proto.STRING, + number=5, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/provenance.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/provenance.py new file mode 100644 index 000000000000..b09cbad6cbdd --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/provenance.py @@ -0,0 +1,597 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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='grafeas.v1', + manifest={ + 'BuildProvenance', + 'Source', + 'FileHashes', + 'Hash', + 'Command', + 'Artifact', + 'SourceContext', + 'AliasContext', + 'CloudRepoSourceContext', + 'GerritSourceContext', + 'GitSourceContext', + 'RepoId', + 'ProjectRepoId', + }, +) + + +class BuildProvenance(proto.Message): + r"""Provenance of a build. Contains all information needed to + verify the full details about the build from source to + completion. + + Attributes: + id (str): + Required. Unique identifier of the build. + project_id (str): + ID of the project. + commands (MutableSequence[grafeas.grafeas_v1.types.Command]): + Commands requested by the build. + built_artifacts (MutableSequence[grafeas.grafeas_v1.types.Artifact]): + Output of the build. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Time at which the build was created. + start_time (google.protobuf.timestamp_pb2.Timestamp): + Time at which execution of the build was + started. + end_time (google.protobuf.timestamp_pb2.Timestamp): + Time at which execution of the build was + finished. + creator (str): + E-mail address of the user who initiated this + build. Note that this was the user's e-mail + address at the time the build was initiated; + this address may not represent the same end-user + for all time. + logs_uri (str): + URI where any logs for this provenance were + written. + source_provenance (grafeas.grafeas_v1.types.Source): + Details of the Source input to the build. + trigger_id (str): + Trigger identifier if the build was triggered + automatically; empty if not. + build_options (MutableMapping[str, str]): + Special options applied to this build. This + is a catch-all field where build providers can + enter any desired additional details. + builder_version (str): + Version string of the builder at the time + this build was executed. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + project_id: str = proto.Field( + proto.STRING, + number=2, + ) + commands: MutableSequence['Command'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='Command', + ) + built_artifacts: MutableSequence['Artifact'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='Artifact', + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=7, + message=timestamp_pb2.Timestamp, + ) + creator: str = proto.Field( + proto.STRING, + number=8, + ) + logs_uri: str = proto.Field( + proto.STRING, + number=9, + ) + source_provenance: 'Source' = proto.Field( + proto.MESSAGE, + number=10, + message='Source', + ) + trigger_id: str = proto.Field( + proto.STRING, + number=11, + ) + build_options: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=12, + ) + builder_version: str = proto.Field( + proto.STRING, + number=13, + ) + + +class Source(proto.Message): + r"""Source describes the location of the source used for the + build. + + Attributes: + artifact_storage_source_uri (str): + If provided, the input binary artifacts for + the build came from this location. + file_hashes (MutableMapping[str, grafeas.grafeas_v1.types.FileHashes]): + Hash(es) of the build source, which can be + used to verify that the original source + integrity was maintained in the build. + + The keys to this map are file paths used as + build source and the values contain the hash + values for those files. + + If the build source came in a single package + such as a gzipped tarfile (.tar.gz), the + FileHash will be for the single path to that + file. + context (grafeas.grafeas_v1.types.SourceContext): + If provided, the source code used for the + build came from this location. + additional_contexts (MutableSequence[grafeas.grafeas_v1.types.SourceContext]): + If provided, some of the source code used for + the build may be found in these locations, in + the case where the source repository had + multiple remotes or submodules. This list will + not include the context specified in the context + field. + """ + + artifact_storage_source_uri: str = proto.Field( + proto.STRING, + number=1, + ) + file_hashes: MutableMapping[str, 'FileHashes'] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=2, + message='FileHashes', + ) + context: 'SourceContext' = proto.Field( + proto.MESSAGE, + number=3, + message='SourceContext', + ) + additional_contexts: MutableSequence['SourceContext'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='SourceContext', + ) + + +class FileHashes(proto.Message): + r"""Container message for hashes of byte content of files, used + in source messages to verify integrity of source input to the + build. + + Attributes: + file_hash (MutableSequence[grafeas.grafeas_v1.types.Hash]): + Required. Collection of file hashes. + """ + + file_hash: MutableSequence['Hash'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='Hash', + ) + + +class Hash(proto.Message): + r"""Container message for hash values. + + Attributes: + type_ (str): + Required. The type of hash that was + performed, e.g. "SHA-256". + value (bytes): + Required. The hash value. + """ + + type_: str = proto.Field( + proto.STRING, + number=1, + ) + value: bytes = proto.Field( + proto.BYTES, + number=2, + ) + + +class Command(proto.Message): + r"""Command describes a step performed as part of the build + pipeline. + + Attributes: + name (str): + Required. Name of the command, as presented on the command + line, or if the command is packaged as a Docker container, + as presented to ``docker pull``. + env (MutableSequence[str]): + Environment variables set before running this + command. + args (MutableSequence[str]): + Command-line arguments used when executing + this command. + dir_ (str): + Working directory (relative to project source + root) used when running this command. + id (str): + Optional unique identifier for this command, used in + wait_for to reference this command as a dependency. + wait_for (MutableSequence[str]): + The ID(s) of the command(s) that this command + depends on. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + env: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + args: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + dir_: str = proto.Field( + proto.STRING, + number=4, + ) + id: str = proto.Field( + proto.STRING, + number=5, + ) + wait_for: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=6, + ) + + +class Artifact(proto.Message): + r"""Artifact describes a build product. + + Attributes: + checksum (str): + Hash or checksum value of a binary, or Docker + Registry 2.0 digest of a container. + id (str): + Artifact ID, if any; for container images, this will be a + URL by digest like + ``gcr.io/projectID/imagename@sha256:123456``. + names (MutableSequence[str]): + Related artifact names. This may be the path to a binary or + jar file, or in the case of a container build, the name used + to push the container image to Google Container Registry, as + presented to ``docker push``. Note that a single Artifact ID + can have multiple names, for example if two tags are applied + to one image. + """ + + checksum: str = proto.Field( + proto.STRING, + number=1, + ) + id: str = proto.Field( + proto.STRING, + number=2, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class SourceContext(proto.Message): + r"""A SourceContext is a reference to a tree of files. A + SourceContext together with a path point to a unique revision of + a single file or directory. + + 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: + cloud_repo (grafeas.grafeas_v1.types.CloudRepoSourceContext): + A SourceContext referring to a revision in a + Google Cloud Source Repo. + + This field is a member of `oneof`_ ``context``. + gerrit (grafeas.grafeas_v1.types.GerritSourceContext): + A SourceContext referring to a Gerrit + project. + + This field is a member of `oneof`_ ``context``. + git (grafeas.grafeas_v1.types.GitSourceContext): + A SourceContext referring to any third party + Git repo (e.g., GitHub). + + This field is a member of `oneof`_ ``context``. + labels (MutableMapping[str, str]): + Labels with user defined metadata. + """ + + cloud_repo: 'CloudRepoSourceContext' = proto.Field( + proto.MESSAGE, + number=1, + oneof='context', + message='CloudRepoSourceContext', + ) + gerrit: 'GerritSourceContext' = proto.Field( + proto.MESSAGE, + number=2, + oneof='context', + message='GerritSourceContext', + ) + git: 'GitSourceContext' = proto.Field( + proto.MESSAGE, + number=3, + oneof='context', + message='GitSourceContext', + ) + labels: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=4, + ) + + +class AliasContext(proto.Message): + r"""An alias to a repo revision. + + Attributes: + kind (grafeas.grafeas_v1.types.AliasContext.Kind): + The alias kind. + name (str): + The alias name. + """ + class Kind(proto.Enum): + r"""The type of an alias. + + Values: + KIND_UNSPECIFIED (0): + Unknown. + FIXED (1): + Git tag. + MOVABLE (2): + Git branch. + OTHER (4): + Used to specify non-standard aliases. For + example, if a Git repo has a ref named + "refs/foo/bar". + """ + KIND_UNSPECIFIED = 0 + FIXED = 1 + MOVABLE = 2 + OTHER = 4 + + kind: Kind = proto.Field( + proto.ENUM, + number=1, + enum=Kind, + ) + name: str = proto.Field( + proto.STRING, + number=2, + ) + + +class CloudRepoSourceContext(proto.Message): + r"""A CloudRepoSourceContext denotes a particular revision in a + Google Cloud Source Repo. + + 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: + repo_id (grafeas.grafeas_v1.types.RepoId): + The ID of the repo. + revision_id (str): + A revision ID. + + This field is a member of `oneof`_ ``revision``. + alias_context (grafeas.grafeas_v1.types.AliasContext): + An alias, which may be a branch or tag. + + This field is a member of `oneof`_ ``revision``. + """ + + repo_id: 'RepoId' = proto.Field( + proto.MESSAGE, + number=1, + message='RepoId', + ) + revision_id: str = proto.Field( + proto.STRING, + number=2, + oneof='revision', + ) + alias_context: 'AliasContext' = proto.Field( + proto.MESSAGE, + number=3, + oneof='revision', + message='AliasContext', + ) + + +class GerritSourceContext(proto.Message): + r"""A SourceContext referring to a Gerrit project. + + 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: + host_uri (str): + The URI of a running Gerrit instance. + gerrit_project (str): + The full project name within the host. + Projects may be nested, so "project/subproject" + is a valid project name. The "repo name" is the + hostURI/project. + revision_id (str): + A revision (commit) ID. + + This field is a member of `oneof`_ ``revision``. + alias_context (grafeas.grafeas_v1.types.AliasContext): + An alias, which may be a branch or tag. + + This field is a member of `oneof`_ ``revision``. + """ + + host_uri: str = proto.Field( + proto.STRING, + number=1, + ) + gerrit_project: str = proto.Field( + proto.STRING, + number=2, + ) + revision_id: str = proto.Field( + proto.STRING, + number=3, + oneof='revision', + ) + alias_context: 'AliasContext' = proto.Field( + proto.MESSAGE, + number=4, + oneof='revision', + message='AliasContext', + ) + + +class GitSourceContext(proto.Message): + r"""A GitSourceContext denotes a particular revision in a third + party Git repository (e.g., GitHub). + + Attributes: + url (str): + Git repository URL. + revision_id (str): + Git commit hash. + """ + + url: str = proto.Field( + proto.STRING, + number=1, + ) + revision_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +class RepoId(proto.Message): + r"""A unique identifier for a Cloud Repo. + + 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: + project_repo_id (grafeas.grafeas_v1.types.ProjectRepoId): + A combination of a project ID and a repo + name. + + This field is a member of `oneof`_ ``id``. + uid (str): + A server-assigned, globally unique + identifier. + + This field is a member of `oneof`_ ``id``. + """ + + project_repo_id: 'ProjectRepoId' = proto.Field( + proto.MESSAGE, + number=1, + oneof='id', + message='ProjectRepoId', + ) + uid: str = proto.Field( + proto.STRING, + number=2, + oneof='id', + ) + + +class ProjectRepoId(proto.Message): + r"""Selects a repo using a Google Cloud Platform project ID + (e.g., winged-cargo-31) and a repo name within that project. + + Attributes: + project_id (str): + The ID of the project. + repo_name (str): + The name of the repo. Leave empty for the + default repo. + """ + + project_id: str = proto.Field( + proto.STRING, + number=1, + ) + repo_name: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/sbom.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/sbom.py new file mode 100644 index 000000000000..e4e85214f8c7 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/sbom.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import common +from grafeas.grafeas_v1.types import intoto_statement + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'SBOMReferenceNote', + 'SBOMReferenceOccurrence', + 'SbomReferenceIntotoPayload', + 'SbomReferenceIntotoPredicate', + }, +) + + +class SBOMReferenceNote(proto.Message): + r"""The note representing an SBOM reference. + + Attributes: + format_ (str): + The format that SBOM takes. E.g. may be spdx, + cyclonedx, etc... + version (str): + The version of the format that the SBOM + takes. E.g. if the format is spdx, the version + may be 2.3. + """ + + format_: str = proto.Field( + proto.STRING, + number=1, + ) + version: str = proto.Field( + proto.STRING, + number=2, + ) + + +class SBOMReferenceOccurrence(proto.Message): + r"""The occurrence representing an SBOM reference as applied to a + specific resource. The occurrence follows the DSSE + specification. See + https://github.com/secure-systems-lab/dsse/blob/master/envelope.md + for more details. + + Attributes: + payload (grafeas.grafeas_v1.types.SbomReferenceIntotoPayload): + The actual payload that contains the SBOM + reference data. + payload_type (str): + The kind of payload that + SbomReferenceIntotoPayload takes. Since it's in + the intoto format, this value is expected to be + 'application/vnd.in-toto+json'. + signatures (MutableSequence[grafeas.grafeas_v1.types.EnvelopeSignature]): + The signatures over the payload. + """ + + payload: 'SbomReferenceIntotoPayload' = proto.Field( + proto.MESSAGE, + number=1, + message='SbomReferenceIntotoPayload', + ) + payload_type: str = proto.Field( + proto.STRING, + number=2, + ) + signatures: MutableSequence[common.EnvelopeSignature] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=common.EnvelopeSignature, + ) + + +class SbomReferenceIntotoPayload(proto.Message): + r"""The actual payload that contains the SBOM Reference data. + The payload follows the intoto statement specification. See + https://github.com/in-toto/attestation/blob/main/spec/v1.0/statement.md + for more details. + + Attributes: + type_ (str): + Identifier for the schema of the Statement. + predicate_type (str): + URI identifying the type of the Predicate. + subject (MutableSequence[grafeas.grafeas_v1.types.Subject]): + Set of software artifacts that the + attestation applies to. Each element represents + a single software artifact. + predicate (grafeas.grafeas_v1.types.SbomReferenceIntotoPredicate): + Additional parameters of the Predicate. + Includes the actual data about the SBOM. + """ + + type_: str = proto.Field( + proto.STRING, + number=1, + ) + predicate_type: str = proto.Field( + proto.STRING, + number=2, + ) + subject: MutableSequence[intoto_statement.Subject] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=intoto_statement.Subject, + ) + predicate: 'SbomReferenceIntotoPredicate' = proto.Field( + proto.MESSAGE, + number=4, + message='SbomReferenceIntotoPredicate', + ) + + +class SbomReferenceIntotoPredicate(proto.Message): + r"""A predicate which describes the SBOM being referenced. + + Attributes: + referrer_id (str): + The person or system referring this predicate + to the consumer. + location (str): + The location of the SBOM. + mime_type (str): + The mime type of the SBOM. + digest (MutableMapping[str, str]): + A map of algorithm to digest of the contents + of the SBOM. + """ + + referrer_id: str = proto.Field( + proto.STRING, + number=1, + ) + location: str = proto.Field( + proto.STRING, + number=2, + ) + mime_type: str = proto.Field( + proto.STRING, + number=3, + ) + digest: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/severity.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/severity.py new file mode 100644 index 000000000000..cee526950a5c --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/severity.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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='grafeas.v1', + manifest={ + 'Severity', + }, +) + + +class Severity(proto.Enum): + r"""Note provider assigned severity/impact ranking. + + Values: + SEVERITY_UNSPECIFIED (0): + Unknown. + MINIMAL (1): + Minimal severity. + LOW (2): + Low severity. + MEDIUM (3): + Medium severity. + HIGH (4): + High severity. + CRITICAL (5): + Critical severity. + """ + SEVERITY_UNSPECIFIED = 0 + MINIMAL = 1 + LOW = 2 + MEDIUM = 3 + HIGH = 4 + CRITICAL = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance.py new file mode 100644 index 000000000000..9284bfed9ae0 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance.py @@ -0,0 +1,258 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 any_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'SlsaProvenance', + }, +) + + +class SlsaProvenance(proto.Message): + r""" + + Attributes: + builder (grafeas.grafeas_v1.types.SlsaProvenance.SlsaBuilder): + required + recipe (grafeas.grafeas_v1.types.SlsaProvenance.SlsaRecipe): + Identifies the configuration used for the + build. When combined with materials, this SHOULD + fully describe the build, such that re-running + this recipe results in bit-for-bit identical + output (if the build is reproducible). + metadata (grafeas.grafeas_v1.types.SlsaProvenance.SlsaMetadata): + + materials (MutableSequence[grafeas.grafeas_v1.types.SlsaProvenance.Material]): + The collection of artifacts that influenced + the build including sources, dependencies, build + tools, base images, and so on. This is + considered to be incomplete unless + metadata.completeness.materials is true. Unset + or null is equivalent to empty. + """ + + class SlsaRecipe(proto.Message): + r"""Steps taken to build the artifact. + For a TaskRun, typically each container corresponds to one step + in the recipe. + + Attributes: + type_ (str): + URI indicating what type of recipe was + performed. It determines the meaning of + recipe.entryPoint, recipe.arguments, + recipe.environment, and materials. + defined_in_material (int): + Index in materials containing the recipe + steps that are not implied by recipe.type. For + example, if the recipe type were "make", then + this would point to the source containing the + Makefile, not the make program itself. Set to -1 + if the recipe doesn't come from a material, as + zero is default unset value for int64. + entry_point (str): + String identifying the entry point into the + build. This is often a path to a configuration + file and/or a target label within that file. The + syntax and meaning are defined by recipe.type. + For example, if the recipe type were "make", + then this would reference the directory in which + to run make as well as which target to use. + arguments (google.protobuf.any_pb2.Any): + Collection of all external inputs that + influenced the build on top of + recipe.definedInMaterial and recipe.entryPoint. + For example, if the recipe type were "make", + then this might be the flags passed to make + aside from the target, which is captured in + recipe.entryPoint. Depending on the recipe Type, + the structure may be different. + environment (google.protobuf.any_pb2.Any): + Any other builder-controlled inputs necessary + for correctly evaluating the recipe. Usually + only needed for reproducing the build but not + evaluated as part of policy. Depending on the + recipe Type, the structure may be different. + """ + + type_: str = proto.Field( + proto.STRING, + number=1, + ) + defined_in_material: int = proto.Field( + proto.INT64, + number=2, + ) + entry_point: str = proto.Field( + proto.STRING, + number=3, + ) + arguments: any_pb2.Any = proto.Field( + proto.MESSAGE, + number=4, + message=any_pb2.Any, + ) + environment: any_pb2.Any = proto.Field( + proto.MESSAGE, + number=5, + message=any_pb2.Any, + ) + + class SlsaCompleteness(proto.Message): + r"""Indicates that the builder claims certain fields in this + message to be complete. + + Attributes: + arguments (bool): + If true, the builder claims that + recipe.arguments is complete, meaning that all + external inputs are properly captured in the + recipe. + environment (bool): + If true, the builder claims that + recipe.environment is claimed to be complete. + materials (bool): + If true, the builder claims that materials + are complete, usually through some controls to + prevent network access. Sometimes called + "hermetic". + """ + + arguments: bool = proto.Field( + proto.BOOL, + number=1, + ) + environment: bool = proto.Field( + proto.BOOL, + number=2, + ) + materials: bool = proto.Field( + proto.BOOL, + number=3, + ) + + class SlsaMetadata(proto.Message): + r"""Other properties of the build. + + Attributes: + build_invocation_id (str): + Identifies the particular build invocation, + which can be useful for finding associated logs + or other ad-hoc analysis. The value SHOULD be + globally unique, per in-toto Provenance spec. + build_started_on (google.protobuf.timestamp_pb2.Timestamp): + The timestamp of when the build started. + build_finished_on (google.protobuf.timestamp_pb2.Timestamp): + The timestamp of when the build completed. + completeness (grafeas.grafeas_v1.types.SlsaProvenance.SlsaCompleteness): + Indicates that the builder claims certain + fields in this message to be complete. + reproducible (bool): + If true, the builder claims that running the + recipe on materials will produce bit-for-bit + identical output. + """ + + build_invocation_id: str = proto.Field( + proto.STRING, + number=1, + ) + build_started_on: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + build_finished_on: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + completeness: 'SlsaProvenance.SlsaCompleteness' = proto.Field( + proto.MESSAGE, + number=4, + message='SlsaProvenance.SlsaCompleteness', + ) + reproducible: bool = proto.Field( + proto.BOOL, + number=5, + ) + + class SlsaBuilder(proto.Message): + r""" + + Attributes: + id (str): + + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + + class Material(proto.Message): + r""" + + Attributes: + uri (str): + + digest (MutableMapping[str, str]): + + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + digest: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=2, + ) + + builder: SlsaBuilder = proto.Field( + proto.MESSAGE, + number=1, + message=SlsaBuilder, + ) + recipe: SlsaRecipe = proto.Field( + proto.MESSAGE, + number=2, + message=SlsaRecipe, + ) + metadata: SlsaMetadata = proto.Field( + proto.MESSAGE, + number=3, + message=SlsaMetadata, + ) + materials: MutableSequence[Material] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=Material, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance_zero_two.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance_zero_two.py new file mode 100644 index 000000000000..c7bb72971913 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance_zero_two.py @@ -0,0 +1,242 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 struct_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'SlsaProvenanceZeroTwo', + }, +) + + +class SlsaProvenanceZeroTwo(proto.Message): + r"""See full explanation of fields at slsa.dev/provenance/v0.2. + + Attributes: + builder (grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo.SlsaBuilder): + + build_type (str): + + invocation (grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo.SlsaInvocation): + + build_config (google.protobuf.struct_pb2.Struct): + + metadata (grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo.SlsaMetadata): + + materials (MutableSequence[grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo.SlsaMaterial]): + + """ + + class SlsaBuilder(proto.Message): + r"""Identifies the entity that executed the recipe, which is + trusted to have correctly performed the operation and populated + this provenance. + + Attributes: + id (str): + + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + + class SlsaMaterial(proto.Message): + r"""The collection of artifacts that influenced the build + including sources, dependencies, build tools, base images, and + so on. + + Attributes: + uri (str): + + digest (MutableMapping[str, str]): + + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + digest: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=2, + ) + + class SlsaInvocation(proto.Message): + r"""Identifies the event that kicked off the build. + + Attributes: + config_source (grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo.SlsaConfigSource): + + parameters (google.protobuf.struct_pb2.Struct): + + environment (google.protobuf.struct_pb2.Struct): + + """ + + config_source: 'SlsaProvenanceZeroTwo.SlsaConfigSource' = proto.Field( + proto.MESSAGE, + number=1, + message='SlsaProvenanceZeroTwo.SlsaConfigSource', + ) + parameters: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=2, + message=struct_pb2.Struct, + ) + environment: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=3, + message=struct_pb2.Struct, + ) + + class SlsaConfigSource(proto.Message): + r"""Describes where the config file that kicked off the build + came from. This is effectively a pointer to the source where + buildConfig came from. + + Attributes: + uri (str): + + digest (MutableMapping[str, str]): + + entry_point (str): + + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + digest: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=2, + ) + entry_point: str = proto.Field( + proto.STRING, + number=3, + ) + + class SlsaMetadata(proto.Message): + r"""Other properties of the build. + + Attributes: + build_invocation_id (str): + + build_started_on (google.protobuf.timestamp_pb2.Timestamp): + + build_finished_on (google.protobuf.timestamp_pb2.Timestamp): + + completeness (grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo.SlsaCompleteness): + + reproducible (bool): + + """ + + build_invocation_id: str = proto.Field( + proto.STRING, + number=1, + ) + build_started_on: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + build_finished_on: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + completeness: 'SlsaProvenanceZeroTwo.SlsaCompleteness' = proto.Field( + proto.MESSAGE, + number=4, + message='SlsaProvenanceZeroTwo.SlsaCompleteness', + ) + reproducible: bool = proto.Field( + proto.BOOL, + number=5, + ) + + class SlsaCompleteness(proto.Message): + r"""Indicates that the builder claims certain fields in this + message to be complete. + + Attributes: + parameters (bool): + + environment (bool): + + materials (bool): + + """ + + parameters: bool = proto.Field( + proto.BOOL, + number=1, + ) + environment: bool = proto.Field( + proto.BOOL, + number=2, + ) + materials: bool = proto.Field( + proto.BOOL, + number=3, + ) + + builder: SlsaBuilder = proto.Field( + proto.MESSAGE, + number=1, + message=SlsaBuilder, + ) + build_type: str = proto.Field( + proto.STRING, + number=2, + ) + invocation: SlsaInvocation = proto.Field( + proto.MESSAGE, + number=3, + message=SlsaInvocation, + ) + build_config: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=4, + message=struct_pb2.Struct, + ) + metadata: SlsaMetadata = proto.Field( + proto.MESSAGE, + number=5, + message=SlsaMetadata, + ) + materials: MutableSequence[SlsaMaterial] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=SlsaMaterial, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/upgrade.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/upgrade.py new file mode 100644 index 000000000000..a7181f7a083f --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/upgrade.py @@ -0,0 +1,266 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import package as g_package + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'UpgradeNote', + 'UpgradeDistribution', + 'WindowsUpdate', + 'UpgradeOccurrence', + }, +) + + +class UpgradeNote(proto.Message): + r"""An Upgrade Note represents a potential upgrade of a package to a + given version. For each package version combination (i.e. bash 4.0, + bash 4.1, bash 4.1.2), there will be an Upgrade Note. For Windows, + windows_update field represents the information related to the + update. + + Attributes: + package (str): + Required for non-Windows OS. The package this + Upgrade is for. + version (grafeas.grafeas_v1.types.Version): + Required for non-Windows OS. The version of + the package in machine + human readable form. + distributions (MutableSequence[grafeas.grafeas_v1.types.UpgradeDistribution]): + Metadata about the upgrade for each specific + operating system. + windows_update (grafeas.grafeas_v1.types.WindowsUpdate): + Required for Windows OS. Represents the + metadata about the Windows update. + """ + + package: str = proto.Field( + proto.STRING, + number=1, + ) + version: g_package.Version = proto.Field( + proto.MESSAGE, + number=2, + message=g_package.Version, + ) + distributions: MutableSequence['UpgradeDistribution'] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message='UpgradeDistribution', + ) + windows_update: 'WindowsUpdate' = proto.Field( + proto.MESSAGE, + number=4, + message='WindowsUpdate', + ) + + +class UpgradeDistribution(proto.Message): + r"""The Upgrade Distribution represents metadata about the + Upgrade for each operating system (CPE). Some distributions have + additional metadata around updates, classifying them into + various categories and severities. + + Attributes: + cpe_uri (str): + Required - The specific operating system this + metadata applies to. See + https://cpe.mitre.org/specification/. + classification (str): + The operating system classification of this Upgrade, as + specified by the upstream operating system upgrade feed. For + Windows the classification is one of the category_ids listed + at + https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ff357803(v=vs.85) + severity (str): + The severity as specified by the upstream + operating system. + cve (MutableSequence[str]): + The cve tied to this Upgrade. + """ + + cpe_uri: str = proto.Field( + proto.STRING, + number=1, + ) + classification: str = proto.Field( + proto.STRING, + number=2, + ) + severity: str = proto.Field( + proto.STRING, + number=3, + ) + cve: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + + +class WindowsUpdate(proto.Message): + r"""Windows Update represents the metadata about the update for + the Windows operating system. The fields in this message come + from the Windows Update API documented at + https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdate. + + Attributes: + identity (grafeas.grafeas_v1.types.WindowsUpdate.Identity): + Required - The unique identifier for the + update. + title (str): + The localized title of the update. + description (str): + The localized description of the update. + categories (MutableSequence[grafeas.grafeas_v1.types.WindowsUpdate.Category]): + The list of categories to which the update + belongs. + kb_article_ids (MutableSequence[str]): + The Microsoft Knowledge Base article IDs that + are associated with the update. + support_url (str): + The hyperlink to the support information for + the update. + last_published_timestamp (google.protobuf.timestamp_pb2.Timestamp): + The last published timestamp of the update. + """ + + class Identity(proto.Message): + r"""The unique identifier of the update. + + Attributes: + update_id (str): + The revision independent identifier of the + update. + revision (int): + The revision number of the update. + """ + + update_id: str = proto.Field( + proto.STRING, + number=1, + ) + revision: int = proto.Field( + proto.INT32, + number=2, + ) + + class Category(proto.Message): + r"""The category to which the update belongs. + + Attributes: + category_id (str): + The identifier of the category. + name (str): + The localized name of the category. + """ + + category_id: str = proto.Field( + proto.STRING, + number=1, + ) + name: str = proto.Field( + proto.STRING, + number=2, + ) + + identity: Identity = proto.Field( + proto.MESSAGE, + number=1, + message=Identity, + ) + title: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + categories: MutableSequence[Category] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=Category, + ) + kb_article_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + support_url: str = proto.Field( + proto.STRING, + number=6, + ) + last_published_timestamp: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=7, + message=timestamp_pb2.Timestamp, + ) + + +class UpgradeOccurrence(proto.Message): + r"""An Upgrade Occurrence represents that a specific resource_url could + install a specific upgrade. This presence is supplied via local + sources (i.e. it is present in the mirror and the running system has + noticed its availability). For Windows, both distribution and + windows_update contain information for the Windows update. + + Attributes: + package (str): + Required for non-Windows OS. The package this + Upgrade is for. + parsed_version (grafeas.grafeas_v1.types.Version): + Required for non-Windows OS. The version of + the package in a machine + human readable form. + distribution (grafeas.grafeas_v1.types.UpgradeDistribution): + Metadata about the upgrade for available for the specific + operating system for the resource_url. This allows efficient + filtering, as well as making it easier to use the + occurrence. + windows_update (grafeas.grafeas_v1.types.WindowsUpdate): + Required for Windows OS. Represents the + metadata about the Windows update. + """ + + package: str = proto.Field( + proto.STRING, + number=1, + ) + parsed_version: g_package.Version = proto.Field( + proto.MESSAGE, + number=3, + message=g_package.Version, + ) + distribution: 'UpgradeDistribution' = proto.Field( + proto.MESSAGE, + number=4, + message='UpgradeDistribution', + ) + windows_update: 'WindowsUpdate' = proto.Field( + proto.MESSAGE, + number=5, + message='WindowsUpdate', + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vex.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vex.py new file mode 100644 index 000000000000..813c1613f2b7 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vex.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import common + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'VulnerabilityAssessmentNote', + }, +) + + +class VulnerabilityAssessmentNote(proto.Message): + r"""A single VulnerabilityAssessmentNote represents + one particular product's vulnerability assessment for one CVE. + + Attributes: + title (str): + The title of the note. E.g. ``Vex-Debian-11.4`` + short_description (str): + A one sentence description of this Vex. + long_description (str): + A detailed description of this Vex. + language_code (str): + Identifies the language used by this + document, corresponding to IETF BCP 47 / RFC + 5646. + publisher (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Publisher): + Publisher details of this Note. + product (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Product): + The product affected by this vex. + assessment (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment): + Represents a vulnerability assessment for the + product. + """ + + class Publisher(proto.Message): + r"""Publisher contains information about the publisher of + this Note. + (-- api-linter: core::0123::resource-annotation=disabled + aip.dev/not-precedent: Publisher is not a separate resource. --) + + Attributes: + name (str): + Name of the publisher. + Examples: 'Google', 'Google Cloud Platform'. + issuing_authority (str): + Provides information about the authority of + the issuing party to release the document, in + particular, the party's constituency and + responsibilities or other obligations. + publisher_namespace (str): + The context or namespace. + Contains a URL which is under control of the + issuing party and can be used as a globally + unique identifier for that issuing party. + Example: https://csaf.io + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + issuing_authority: str = proto.Field( + proto.STRING, + number=2, + ) + publisher_namespace: str = proto.Field( + proto.STRING, + number=3, + ) + + class Product(proto.Message): + r"""Product contains information about a product and how to + uniquely identify it. + (-- api-linter: core::0123::resource-annotation=disabled + aip.dev/not-precedent: Product is not a separate resource. --) + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Name of the product. + id (str): + Token that identifies a product so that it + can be referred to from other parts in the + document. There is no predefined format as long + as it uniquely identifies a group in the context + of the current document. + generic_uri (str): + Contains a URI which is vendor-specific. + Example: The artifact repository URL of an + image. + + This field is a member of `oneof`_ ``identifier``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + id: str = proto.Field( + proto.STRING, + number=2, + ) + generic_uri: str = proto.Field( + proto.STRING, + number=3, + oneof='identifier', + ) + + class Assessment(proto.Message): + r"""Assessment provides all information that is related to a + single vulnerability for this product. + + Attributes: + cve (str): + Holds the MITRE standard Common Vulnerabilities and + Exposures (CVE) tracking number for the vulnerability. + Deprecated: Use vulnerability_id instead to denote CVEs. + vulnerability_id (str): + The vulnerability identifier for this + Assessment. Will hold one of common identifiers + e.g. CVE, GHSA etc. + short_description (str): + A one sentence description of this Vex. + long_description (str): + A detailed description of this Vex. + related_uris (MutableSequence[grafeas.grafeas_v1.types.RelatedUrl]): + Holds a list of references associated with + this vulnerability item and assessment. These + uris have additional information about the + vulnerability and the assessment itself. E.g. + Link to a document which details how this + assessment concluded the state of this + vulnerability. + state (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.State): + Provides the state of this Vulnerability + assessment. + impacts (MutableSequence[str]): + Contains information about the impact of this + vulnerability, this will change with time. + justification (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Justification): + Justification provides the justification when the state of + the assessment if NOT_AFFECTED. + remediations (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Remediation]): + Specifies details on how to handle (and + presumably, fix) a vulnerability. + """ + class State(proto.Enum): + r"""Provides the state of this Vulnerability assessment. + + Values: + STATE_UNSPECIFIED (0): + No state is specified. + AFFECTED (1): + This product is known to be affected by this + vulnerability. + NOT_AFFECTED (2): + This product is known to be not affected by + this vulnerability. + FIXED (3): + This product contains a fix for this + vulnerability. + UNDER_INVESTIGATION (4): + It is not known yet whether these versions + are or are not affected by the vulnerability. + However, it is still under investigation. + """ + STATE_UNSPECIFIED = 0 + AFFECTED = 1 + NOT_AFFECTED = 2 + FIXED = 3 + UNDER_INVESTIGATION = 4 + + class Justification(proto.Message): + r"""Justification provides the justification when the state of the + assessment if NOT_AFFECTED. + + Attributes: + justification_type (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Justification.JustificationType): + The justification type for this + vulnerability. + details (str): + Additional details on why this justification + was chosen. + """ + class JustificationType(proto.Enum): + r"""Provides the type of justification. + + Values: + JUSTIFICATION_TYPE_UNSPECIFIED (0): + JUSTIFICATION_TYPE_UNSPECIFIED. + COMPONENT_NOT_PRESENT (1): + The vulnerable component is not present in + the product. + VULNERABLE_CODE_NOT_PRESENT (2): + The vulnerable code is not present. Typically + this case occurs when source code is configured + or built in a way that excludes the vulnerable + code. + VULNERABLE_CODE_NOT_IN_EXECUTE_PATH (3): + The vulnerable code can not be executed. + Typically this case occurs when the product + includes the vulnerable code but does not call + or use the vulnerable code. + VULNERABLE_CODE_CANNOT_BE_CONTROLLED_BY_ADVERSARY (4): + The vulnerable code cannot be controlled by + an attacker to exploit the vulnerability. + INLINE_MITIGATIONS_ALREADY_EXIST (5): + The product includes built-in protections or + features that prevent exploitation of the + vulnerability. These built-in protections cannot + be subverted by the attacker and cannot be + configured or disabled by the user. These + mitigations completely prevent exploitation + based on known attack vectors. + """ + JUSTIFICATION_TYPE_UNSPECIFIED = 0 + COMPONENT_NOT_PRESENT = 1 + VULNERABLE_CODE_NOT_PRESENT = 2 + VULNERABLE_CODE_NOT_IN_EXECUTE_PATH = 3 + VULNERABLE_CODE_CANNOT_BE_CONTROLLED_BY_ADVERSARY = 4 + INLINE_MITIGATIONS_ALREADY_EXIST = 5 + + justification_type: 'VulnerabilityAssessmentNote.Assessment.Justification.JustificationType' = proto.Field( + proto.ENUM, + number=1, + enum='VulnerabilityAssessmentNote.Assessment.Justification.JustificationType', + ) + details: str = proto.Field( + proto.STRING, + number=2, + ) + + class Remediation(proto.Message): + r"""Specifies details on how to handle (and presumably, fix) a + vulnerability. + + Attributes: + remediation_type (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Remediation.RemediationType): + The type of remediation that can be applied. + details (str): + Contains a comprehensive human-readable + discussion of the remediation. + remediation_uri (grafeas.grafeas_v1.types.RelatedUrl): + Contains the URL where to obtain the + remediation. + """ + class RemediationType(proto.Enum): + r"""The type of remediation that can be applied. + + Values: + REMEDIATION_TYPE_UNSPECIFIED (0): + No remediation type specified. + MITIGATION (1): + A MITIGATION is available. + NO_FIX_PLANNED (2): + No fix is planned. + NONE_AVAILABLE (3): + Not available. + VENDOR_FIX (4): + A vendor fix is available. + WORKAROUND (5): + A workaround is available. + """ + REMEDIATION_TYPE_UNSPECIFIED = 0 + MITIGATION = 1 + NO_FIX_PLANNED = 2 + NONE_AVAILABLE = 3 + VENDOR_FIX = 4 + WORKAROUND = 5 + + remediation_type: 'VulnerabilityAssessmentNote.Assessment.Remediation.RemediationType' = proto.Field( + proto.ENUM, + number=1, + enum='VulnerabilityAssessmentNote.Assessment.Remediation.RemediationType', + ) + details: str = proto.Field( + proto.STRING, + number=2, + ) + remediation_uri: common.RelatedUrl = proto.Field( + proto.MESSAGE, + number=3, + message=common.RelatedUrl, + ) + + cve: str = proto.Field( + proto.STRING, + number=1, + ) + vulnerability_id: str = proto.Field( + proto.STRING, + number=9, + ) + short_description: str = proto.Field( + proto.STRING, + number=2, + ) + long_description: str = proto.Field( + proto.STRING, + number=3, + ) + related_uris: MutableSequence[common.RelatedUrl] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=common.RelatedUrl, + ) + state: 'VulnerabilityAssessmentNote.Assessment.State' = proto.Field( + proto.ENUM, + number=5, + enum='VulnerabilityAssessmentNote.Assessment.State', + ) + impacts: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=6, + ) + justification: 'VulnerabilityAssessmentNote.Assessment.Justification' = proto.Field( + proto.MESSAGE, + number=7, + message='VulnerabilityAssessmentNote.Assessment.Justification', + ) + remediations: MutableSequence['VulnerabilityAssessmentNote.Assessment.Remediation'] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message='VulnerabilityAssessmentNote.Assessment.Remediation', + ) + + title: str = proto.Field( + proto.STRING, + number=1, + ) + short_description: str = proto.Field( + proto.STRING, + number=2, + ) + long_description: str = proto.Field( + proto.STRING, + number=3, + ) + language_code: str = proto.Field( + proto.STRING, + number=4, + ) + publisher: Publisher = proto.Field( + proto.MESSAGE, + number=5, + message=Publisher, + ) + product: Product = proto.Field( + proto.MESSAGE, + number=6, + message=Product, + ) + assessment: Assessment = proto.Field( + proto.MESSAGE, + number=7, + message=Assessment, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vulnerability.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vulnerability.py new file mode 100644 index 000000000000..97000d7d501b --- /dev/null +++ b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vulnerability.py @@ -0,0 +1,594 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import common +from grafeas.grafeas_v1.types import cvss +from grafeas.grafeas_v1.types import package +from grafeas.grafeas_v1.types import severity as g_severity +from grafeas.grafeas_v1.types import vex + + +__protobuf__ = proto.module( + package='grafeas.v1', + manifest={ + 'VulnerabilityNote', + 'VulnerabilityOccurrence', + }, +) + + +class VulnerabilityNote(proto.Message): + r"""A security vulnerability that can be found in resources. + + Attributes: + cvss_score (float): + The CVSS score of this vulnerability. CVSS + score is on a scale of 0 - 10 where 0 indicates + low severity and 10 indicates high severity. + severity (grafeas.grafeas_v1.types.Severity): + The note provider assigned severity of this + vulnerability. + details (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityNote.Detail]): + Details of all known distros and packages + affected by this vulnerability. + cvss_v3 (grafeas.grafeas_v1.types.CVSSv3): + The full description of the CVSSv3 for this + vulnerability. + windows_details (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityNote.WindowsDetail]): + Windows details get their own format because + the information format and model don't match a + normal detail. Specifically Windows updates are + done as patches, thus Windows vulnerabilities + really are a missing package, rather than a + package being at an incorrect version. + source_update_time (google.protobuf.timestamp_pb2.Timestamp): + The time this information was last changed at + the source. This is an upstream timestamp from + the underlying information source - e.g. Ubuntu + security tracker. + cvss_version (grafeas.grafeas_v1.types.CVSSVersion): + CVSS version used to populate cvss_score and severity. + cvss_v2 (grafeas.grafeas_v1.types.CVSS): + The full description of the v2 CVSS for this + vulnerability. + """ + + class Detail(proto.Message): + r"""A detail for a distro and package affected by this + vulnerability and its associated fix (if one is available). + + Attributes: + severity_name (str): + The distro assigned severity of this + vulnerability. + description (str): + A vendor-specific description of this + vulnerability. + package_type (str): + The type of package; whether native or non + native (e.g., ruby gems, node.js packages, + etc.). + affected_cpe_uri (str): + Required. The `CPE + URI `__ this + vulnerability affects. + affected_package (str): + Required. The package this vulnerability + affects. + affected_version_start (grafeas.grafeas_v1.types.Version): + The version number at the start of an interval in which this + vulnerability exists. A vulnerability can affect a package + between version numbers that are disjoint sets of intervals + (example: [1.0.0-1.1.0], [2.4.6-2.4.8] and [4.5.6-4.6.8]) + each of which will be represented in its own Detail. If a + specific affected version is provided by a vulnerability + database, affected_version_start and affected_version_end + will be the same in that Detail. + affected_version_end (grafeas.grafeas_v1.types.Version): + The version number at the end of an interval in which this + vulnerability exists. A vulnerability can affect a package + between version numbers that are disjoint sets of intervals + (example: [1.0.0-1.1.0], [2.4.6-2.4.8] and [4.5.6-4.6.8]) + each of which will be represented in its own Detail. If a + specific affected version is provided by a vulnerability + database, affected_version_start and affected_version_end + will be the same in that Detail. + fixed_cpe_uri (str): + The distro recommended `CPE + URI `__ to update to + that contains a fix for this vulnerability. It is possible + for this to be different from the affected_cpe_uri. + fixed_package (str): + The distro recommended package to update to that contains a + fix for this vulnerability. It is possible for this to be + different from the affected_package. + fixed_version (grafeas.grafeas_v1.types.Version): + The distro recommended version to update to + that contains a fix for this vulnerability. + Setting this to VersionKind.MAXIMUM means no + such version is yet available. + is_obsolete (bool): + Whether this detail is obsolete. Occurrences + are expected not to point to obsolete details. + source_update_time (google.protobuf.timestamp_pb2.Timestamp): + The time this information was last changed at + the source. This is an upstream timestamp from + the underlying information source - e.g. Ubuntu + security tracker. + source (str): + The source from which the information in this + Detail was obtained. + vendor (str): + The name of the vendor of the product. + """ + + severity_name: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + package_type: str = proto.Field( + proto.STRING, + number=3, + ) + affected_cpe_uri: str = proto.Field( + proto.STRING, + number=4, + ) + affected_package: str = proto.Field( + proto.STRING, + number=5, + ) + affected_version_start: package.Version = proto.Field( + proto.MESSAGE, + number=6, + message=package.Version, + ) + affected_version_end: package.Version = proto.Field( + proto.MESSAGE, + number=7, + message=package.Version, + ) + fixed_cpe_uri: str = proto.Field( + proto.STRING, + number=8, + ) + fixed_package: str = proto.Field( + proto.STRING, + number=9, + ) + fixed_version: package.Version = proto.Field( + proto.MESSAGE, + number=10, + message=package.Version, + ) + is_obsolete: bool = proto.Field( + proto.BOOL, + number=11, + ) + source_update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=12, + message=timestamp_pb2.Timestamp, + ) + source: str = proto.Field( + proto.STRING, + number=13, + ) + vendor: str = proto.Field( + proto.STRING, + number=14, + ) + + class WindowsDetail(proto.Message): + r""" + + Attributes: + cpe_uri (str): + Required. The `CPE + URI `__ this + vulnerability affects. + name (str): + Required. The name of this vulnerability. + description (str): + The description of this vulnerability. + fixing_kbs (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityNote.WindowsDetail.KnowledgeBase]): + Required. The names of the KBs which have + hotfixes to mitigate this vulnerability. Note + that there may be multiple hotfixes (and thus + multiple KBs) that mitigate a given + vulnerability. Currently any listed KBs presence + is considered a fix. + """ + + class KnowledgeBase(proto.Message): + r""" + + Attributes: + name (str): + The KB name (generally of the form KB[0-9]+ (e.g., + KB123456)). + url (str): + A link to the KB in the [Windows update catalog] + (https://www.catalog.update.microsoft.com/). + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + url: str = proto.Field( + proto.STRING, + number=2, + ) + + cpe_uri: str = proto.Field( + proto.STRING, + number=1, + ) + name: str = proto.Field( + proto.STRING, + number=2, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + fixing_kbs: MutableSequence['VulnerabilityNote.WindowsDetail.KnowledgeBase'] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message='VulnerabilityNote.WindowsDetail.KnowledgeBase', + ) + + cvss_score: float = proto.Field( + proto.FLOAT, + number=1, + ) + severity: g_severity.Severity = proto.Field( + proto.ENUM, + number=2, + enum=g_severity.Severity, + ) + details: MutableSequence[Detail] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=Detail, + ) + cvss_v3: cvss.CVSSv3 = proto.Field( + proto.MESSAGE, + number=4, + message=cvss.CVSSv3, + ) + windows_details: MutableSequence[WindowsDetail] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=WindowsDetail, + ) + source_update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + cvss_version: cvss.CVSSVersion = proto.Field( + proto.ENUM, + number=7, + enum=cvss.CVSSVersion, + ) + cvss_v2: cvss.CVSS = proto.Field( + proto.MESSAGE, + number=8, + message=cvss.CVSS, + ) + + +class VulnerabilityOccurrence(proto.Message): + r"""An occurrence of a severity vulnerability on a resource. + + Attributes: + type_ (str): + The type of package; whether native or non + native (e.g., ruby gems, node.js packages, + etc.). + severity (grafeas.grafeas_v1.types.Severity): + Output only. The note provider assigned + severity of this vulnerability. + cvss_score (float): + Output only. The CVSS score of this + vulnerability. CVSS score is on a scale of 0 - + 10 where 0 indicates low severity and 10 + indicates high severity. + cvssv3 (grafeas.grafeas_v1.types.CVSS): + The cvss v3 score for the vulnerability. + package_issue (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityOccurrence.PackageIssue]): + Required. The set of affected locations and + their fixes (if available) within the associated + resource. + short_description (str): + Output only. A one sentence description of + this vulnerability. + long_description (str): + Output only. A detailed description of this + vulnerability. + related_urls (MutableSequence[grafeas.grafeas_v1.types.RelatedUrl]): + Output only. URLs related to this + vulnerability. + effective_severity (grafeas.grafeas_v1.types.Severity): + The distro assigned severity for this + vulnerability when it is available, otherwise + this is the note provider assigned severity. + + When there are multiple PackageIssues for this + vulnerability, they can have different effective + severities because some might be provided by the + distro while others are provided by the language + ecosystem for a language pack. For this reason, + it is advised to use the effective severity on + the PackageIssue level. In the case where + multiple PackageIssues have differing effective + severities, this field should be the highest + severity for any of the PackageIssues. + fix_available (bool): + Output only. Whether at least one of the + affected packages has a fix available. + cvss_version (grafeas.grafeas_v1.types.CVSSVersion): + Output only. CVSS version used to populate cvss_score and + severity. + cvss_v2 (grafeas.grafeas_v1.types.CVSS): + The cvss v2 score for the vulnerability. + vex_assessment (grafeas.grafeas_v1.types.VulnerabilityOccurrence.VexAssessment): + + extra_details (str): + Occurrence-specific extra details about the + vulnerability. + """ + + class PackageIssue(proto.Message): + r"""A detail for a distro and package this vulnerability + occurrence was found in and its associated fix (if one is + available). + + Attributes: + affected_cpe_uri (str): + Required. The `CPE + URI `__ this + vulnerability was found in. + affected_package (str): + Required. The package this vulnerability was + found in. + affected_version (grafeas.grafeas_v1.types.Version): + Required. The version of the package that is + installed on the resource affected by this + vulnerability. + fixed_cpe_uri (str): + The `CPE URI `__ this + vulnerability was fixed in. It is possible for this to be + different from the affected_cpe_uri. + fixed_package (str): + The package this vulnerability was fixed in. It is possible + for this to be different from the affected_package. + fixed_version (grafeas.grafeas_v1.types.Version): + Required. The version of the package this + vulnerability was fixed in. Setting this to + VersionKind.MAXIMUM means no fix is yet + available. + fix_available (bool): + Output only. Whether a fix is available for + this package. + package_type (str): + The type of package (e.g. OS, MAVEN, GO). + effective_severity (grafeas.grafeas_v1.types.Severity): + The distro or language system assigned + severity for this vulnerability when that is + available and note provider assigned severity + when it is not available. + file_location (MutableSequence[grafeas.grafeas_v1.types.FileLocation]): + The location at which this package was found. + """ + + affected_cpe_uri: str = proto.Field( + proto.STRING, + number=1, + ) + affected_package: str = proto.Field( + proto.STRING, + number=2, + ) + affected_version: package.Version = proto.Field( + proto.MESSAGE, + number=3, + message=package.Version, + ) + fixed_cpe_uri: str = proto.Field( + proto.STRING, + number=4, + ) + fixed_package: str = proto.Field( + proto.STRING, + number=5, + ) + fixed_version: package.Version = proto.Field( + proto.MESSAGE, + number=6, + message=package.Version, + ) + fix_available: bool = proto.Field( + proto.BOOL, + number=7, + ) + package_type: str = proto.Field( + proto.STRING, + number=8, + ) + effective_severity: g_severity.Severity = proto.Field( + proto.ENUM, + number=9, + enum=g_severity.Severity, + ) + file_location: MutableSequence[common.FileLocation] = proto.RepeatedField( + proto.MESSAGE, + number=10, + message=common.FileLocation, + ) + + class VexAssessment(proto.Message): + r"""VexAssessment provides all publisher provided Vex information + that is related to this vulnerability. + + Attributes: + cve (str): + Holds the MITRE standard Common Vulnerabilities and + Exposures (CVE) tracking number for the vulnerability. + Deprecated: Use vulnerability_id instead to denote CVEs. + vulnerability_id (str): + The vulnerability identifier for this + Assessment. Will hold one of common identifiers + e.g. CVE, GHSA etc. + related_uris (MutableSequence[grafeas.grafeas_v1.types.RelatedUrl]): + Holds a list of references associated with + this vulnerability item and assessment. + note_name (str): + The VulnerabilityAssessment note from which this + VexAssessment was generated. This will be of the form: + ``projects/[PROJECT_ID]/notes/[NOTE_ID]``. (-- api-linter: + core::0122::name-suffix=disabled aip.dev/not-precedent: The + suffix is kept for consistency. --) + state (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.State): + Provides the state of this Vulnerability + assessment. + impacts (MutableSequence[str]): + Contains information about the impact of this + vulnerability, this will change with time. + remediations (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Remediation]): + Specifies details on how to handle (and + presumably, fix) a vulnerability. + justification (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Justification): + Justification provides the justification when the state of + the assessment if NOT_AFFECTED. + """ + + cve: str = proto.Field( + proto.STRING, + number=1, + ) + vulnerability_id: str = proto.Field( + proto.STRING, + number=8, + ) + related_uris: MutableSequence[common.RelatedUrl] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=common.RelatedUrl, + ) + note_name: str = proto.Field( + proto.STRING, + number=3, + ) + state: vex.VulnerabilityAssessmentNote.Assessment.State = proto.Field( + proto.ENUM, + number=4, + enum=vex.VulnerabilityAssessmentNote.Assessment.State, + ) + impacts: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + remediations: MutableSequence[vex.VulnerabilityAssessmentNote.Assessment.Remediation] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=vex.VulnerabilityAssessmentNote.Assessment.Remediation, + ) + justification: vex.VulnerabilityAssessmentNote.Assessment.Justification = proto.Field( + proto.MESSAGE, + number=7, + message=vex.VulnerabilityAssessmentNote.Assessment.Justification, + ) + + type_: str = proto.Field( + proto.STRING, + number=1, + ) + severity: g_severity.Severity = proto.Field( + proto.ENUM, + number=2, + enum=g_severity.Severity, + ) + cvss_score: float = proto.Field( + proto.FLOAT, + number=3, + ) + cvssv3: cvss.CVSS = proto.Field( + proto.MESSAGE, + number=10, + message=cvss.CVSS, + ) + package_issue: MutableSequence[PackageIssue] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=PackageIssue, + ) + short_description: str = proto.Field( + proto.STRING, + number=5, + ) + long_description: str = proto.Field( + proto.STRING, + number=6, + ) + related_urls: MutableSequence[common.RelatedUrl] = proto.RepeatedField( + proto.MESSAGE, + number=7, + message=common.RelatedUrl, + ) + effective_severity: g_severity.Severity = proto.Field( + proto.ENUM, + number=8, + enum=g_severity.Severity, + ) + fix_available: bool = proto.Field( + proto.BOOL, + number=9, + ) + cvss_version: cvss.CVSSVersion = proto.Field( + proto.ENUM, + number=11, + enum=cvss.CVSSVersion, + ) + cvss_v2: cvss.CVSS = proto.Field( + proto.MESSAGE, + number=12, + message=cvss.CVSS, + ) + vex_assessment: VexAssessment = proto.Field( + proto.MESSAGE, + number=13, + message=VexAssessment, + ) + extra_details: str = proto.Field( + proto.STRING, + number=14, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/mypy.ini b/owl-bot-staging/grafeas/v1/mypy.ini new file mode 100644 index 000000000000..574c5aed394b --- /dev/null +++ b/owl-bot-staging/grafeas/v1/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/owl-bot-staging/grafeas/v1/noxfile.py b/owl-bot-staging/grafeas/v1/noxfile.py new file mode 100644 index 000000000000..72c4db956057 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/noxfile.py @@ -0,0 +1,280 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 re +import shutil +import subprocess +import sys + + +import nox # type: ignore + +ALL_PYTHON = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", +] + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" +PACKAGE_NAME = 'grafeas' + +BLACK_VERSION = "black==22.3.0" +BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] +DEFAULT_PYTHON_VERSION = "3.13" + +nox.sessions = [ + "unit", + "cover", + "mypy", + "check_lower_bounds" + # exclude update_lower_bounds from default + "docs", + "blacken", + "lint", + "prerelease_deps", +] + +@nox.session(python=ALL_PYTHON) +@nox.parametrize( + "protobuf_implementation", + [ "python", "upb", "cpp" ], +) +def unit(session, protobuf_implementation): + """Run the unit test suite.""" + + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + session.skip("cpp implementation is not supported in python 3.11+") + + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + session.install('-e', '.', "-c", f"testing/constraints-{session.python}.txt") + + # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. + # The 'cpp' implementation requires Protobuf<4. + if protobuf_implementation == "cpp": + session.install("protobuf<4") + + session.run( + 'py.test', + '--quiet', + '--cov=grafeas/grafeas_v1/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)), + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + +@nox.session(python=ALL_PYTHON[-1]) +@nox.parametrize( + "protobuf_implementation", + [ "python", "upb", "cpp" ], +) +def prerelease_deps(session, protobuf_implementation): + """Run the unit test suite against pre-release versions of dependencies.""" + + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + session.skip("cpp implementation is not supported in python 3.11+") + + # Install test environment dependencies + session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') + + # Install the package without dependencies + session.install('-e', '.', '--no-deps') + + # We test the minimum dependency versions using the minimum Python + # version so the lowest python runtime that we test has a corresponding constraints + # file, located at `testing/constraints--.txt`, which contains all of the + # dependencies and extras. + with open( + CURRENT_DIRECTORY + / "testing" + / f"constraints-{ALL_PYTHON[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + session.install(*constraints_deps) + + prerel_deps = [ + "googleapis-common-protos", + "google-api-core", + "google-auth", + # Exclude grpcio!=1.67.0rc1 which does not support python 3.13 + "grpcio!=1.67.0rc1", + "grpcio-status", + "protobuf", + "proto-plus", + ] + + for dep in prerel_deps: + session.install("--pre", "--no-deps", "--upgrade", dep) + + # Remaining dependencies + other_deps = [ + "requests", + ] + session.install(*other_deps) + + # Print out prerelease package versions + + session.run("python", "-c", "import google.api_core; print(google.api_core.__version__)") + session.run("python", "-c", "import google.auth; print(google.auth.__version__)") + session.run("python", "-c", "import grpc; print(grpc.__version__)") + session.run( + "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" + ) + session.run( + "python", "-c", "import proto; print(proto.__version__)" + ) + + session.run( + 'py.test', + '--quiet', + '--cov=grafeas/grafeas_v1/', + '--cov=tests/', + '--cov-config=.coveragerc', + '--cov-report=term', + '--cov-report=html', + os.path.join('tests', 'unit', ''.join(session.posargs)), + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +@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', + '-p', + 'grafeas', + ) + + +@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, + ) diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_async.py new file mode 100644 index 000000000000..9ed3ef3bae74 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchCreateNotes +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_BatchCreateNotes_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 grafeas import grafeas_v1 + + +async def sample_batch_create_notes(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.BatchCreateNotesRequest( + parent="parent_value", + ) + + # Make the request + response = await client.batch_create_notes(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_BatchCreateNotes_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_sync.py new file mode 100644 index 000000000000..096f01fd138e --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchCreateNotes +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_BatchCreateNotes_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 grafeas import grafeas_v1 + + +def sample_batch_create_notes(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.BatchCreateNotesRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_create_notes(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_BatchCreateNotes_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_async.py new file mode 100644 index 000000000000..10d0a30d5906 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchCreateOccurrences +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_BatchCreateOccurrences_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 grafeas import grafeas_v1 + + +async def sample_batch_create_occurrences(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.BatchCreateOccurrencesRequest( + parent="parent_value", + ) + + # Make the request + response = await client.batch_create_occurrences(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_BatchCreateOccurrences_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_sync.py new file mode 100644 index 000000000000..8f3350d81758 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchCreateOccurrences +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_BatchCreateOccurrences_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 grafeas import grafeas_v1 + + +def sample_batch_create_occurrences(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.BatchCreateOccurrencesRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_create_occurrences(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_BatchCreateOccurrences_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_async.py new file mode 100644 index 000000000000..22163012ecf9 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateNote +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_CreateNote_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 grafeas import grafeas_v1 + + +async def sample_create_note(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.CreateNoteRequest( + parent="parent_value", + note_id="note_id_value", + ) + + # Make the request + response = await client.create_note(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_CreateNote_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_sync.py new file mode 100644 index 000000000000..45d9b8827182 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateNote +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_CreateNote_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 grafeas import grafeas_v1 + + +def sample_create_note(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.CreateNoteRequest( + parent="parent_value", + note_id="note_id_value", + ) + + # Make the request + response = client.create_note(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_CreateNote_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_async.py new file mode 100644 index 000000000000..55ad3999e351 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateOccurrence +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_CreateOccurrence_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 grafeas import grafeas_v1 + + +async def sample_create_occurrence(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.CreateOccurrenceRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_occurrence(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_CreateOccurrence_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_sync.py new file mode 100644 index 000000000000..fbb4fd13a857 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateOccurrence +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_CreateOccurrence_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 grafeas import grafeas_v1 + + +def sample_create_occurrence(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.CreateOccurrenceRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_occurrence(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_CreateOccurrence_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_async.py new file mode 100644 index 000000000000..c128ae0f2a90 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteNote +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_DeleteNote_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 grafeas import grafeas_v1 + + +async def sample_delete_note(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.DeleteNoteRequest( + name="name_value", + ) + + # Make the request + await client.delete_note(request=request) + + +# [END containeranalysis_v1_generated_Grafeas_DeleteNote_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_sync.py new file mode 100644 index 000000000000..8311e5af56c1 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteNote +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_DeleteNote_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 grafeas import grafeas_v1 + + +def sample_delete_note(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.DeleteNoteRequest( + name="name_value", + ) + + # Make the request + client.delete_note(request=request) + + +# [END containeranalysis_v1_generated_Grafeas_DeleteNote_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_async.py new file mode 100644 index 000000000000..eb53c4ac9f81 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteOccurrence +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_DeleteOccurrence_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 grafeas import grafeas_v1 + + +async def sample_delete_occurrence(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.DeleteOccurrenceRequest( + name="name_value", + ) + + # Make the request + await client.delete_occurrence(request=request) + + +# [END containeranalysis_v1_generated_Grafeas_DeleteOccurrence_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_sync.py new file mode 100644 index 000000000000..1d3df488a391 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteOccurrence +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_DeleteOccurrence_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 grafeas import grafeas_v1 + + +def sample_delete_occurrence(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.DeleteOccurrenceRequest( + name="name_value", + ) + + # Make the request + client.delete_occurrence(request=request) + + +# [END containeranalysis_v1_generated_Grafeas_DeleteOccurrence_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_async.py new file mode 100644 index 000000000000..eb74332119ed --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetNote +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_GetNote_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 grafeas import grafeas_v1 + + +async def sample_get_note(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.GetNoteRequest( + name="name_value", + ) + + # Make the request + response = await client.get_note(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_GetNote_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_sync.py new file mode 100644 index 000000000000..4026633cc025 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetNote +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_GetNote_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 grafeas import grafeas_v1 + + +def sample_get_note(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.GetNoteRequest( + name="name_value", + ) + + # Make the request + response = client.get_note(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_GetNote_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_async.py new file mode 100644 index 000000000000..cedafd39e047 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetOccurrence +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_GetOccurrence_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 grafeas import grafeas_v1 + + +async def sample_get_occurrence(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.GetOccurrenceRequest( + name="name_value", + ) + + # Make the request + response = await client.get_occurrence(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_GetOccurrence_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_async.py new file mode 100644 index 000000000000..28817551ddf3 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetOccurrenceNote +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_GetOccurrenceNote_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 grafeas import grafeas_v1 + + +async def sample_get_occurrence_note(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.GetOccurrenceNoteRequest( + name="name_value", + ) + + # Make the request + response = await client.get_occurrence_note(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_GetOccurrenceNote_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_sync.py new file mode 100644 index 000000000000..7bf9619cccaf --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetOccurrenceNote +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_GetOccurrenceNote_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 grafeas import grafeas_v1 + + +def sample_get_occurrence_note(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.GetOccurrenceNoteRequest( + name="name_value", + ) + + # Make the request + response = client.get_occurrence_note(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_GetOccurrenceNote_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_sync.py new file mode 100644 index 000000000000..644d7b6f2049 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetOccurrence +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_GetOccurrence_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 grafeas import grafeas_v1 + + +def sample_get_occurrence(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.GetOccurrenceRequest( + name="name_value", + ) + + # Make the request + response = client.get_occurrence(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_GetOccurrence_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_async.py new file mode 100644 index 000000000000..ea4829680ae4 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListNoteOccurrences +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_ListNoteOccurrences_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 grafeas import grafeas_v1 + + +async def sample_list_note_occurrences(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.ListNoteOccurrencesRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_note_occurrences(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END containeranalysis_v1_generated_Grafeas_ListNoteOccurrences_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_sync.py new file mode 100644 index 000000000000..789dcba080e8 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListNoteOccurrences +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_ListNoteOccurrences_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 grafeas import grafeas_v1 + + +def sample_list_note_occurrences(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.ListNoteOccurrencesRequest( + name="name_value", + ) + + # Make the request + page_result = client.list_note_occurrences(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END containeranalysis_v1_generated_Grafeas_ListNoteOccurrences_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_async.py new file mode 100644 index 000000000000..488eb4dad8aa --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListNotes +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_ListNotes_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 grafeas import grafeas_v1 + + +async def sample_list_notes(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.ListNotesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_notes(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END containeranalysis_v1_generated_Grafeas_ListNotes_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_sync.py new file mode 100644 index 000000000000..d1ce09fe5d61 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListNotes +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_ListNotes_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 grafeas import grafeas_v1 + + +def sample_list_notes(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.ListNotesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_notes(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END containeranalysis_v1_generated_Grafeas_ListNotes_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_async.py new file mode 100644 index 000000000000..007d4ef85574 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_async.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListOccurrences +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_ListOccurrences_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 grafeas import grafeas_v1 + + +async def sample_list_occurrences(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.ListOccurrencesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_occurrences(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END containeranalysis_v1_generated_Grafeas_ListOccurrences_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_sync.py new file mode 100644 index 000000000000..d960929c9388 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_sync.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListOccurrences +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_ListOccurrences_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 grafeas import grafeas_v1 + + +def sample_list_occurrences(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.ListOccurrencesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_occurrences(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END containeranalysis_v1_generated_Grafeas_ListOccurrences_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_async.py new file mode 100644 index 000000000000..5a15196348e3 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateNote +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_UpdateNote_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 grafeas import grafeas_v1 + + +async def sample_update_note(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.UpdateNoteRequest( + name="name_value", + ) + + # Make the request + response = await client.update_note(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_UpdateNote_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_sync.py new file mode 100644 index 000000000000..ea0db334ebc1 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateNote +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_UpdateNote_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 grafeas import grafeas_v1 + + +def sample_update_note(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.UpdateNoteRequest( + name="name_value", + ) + + # Make the request + response = client.update_note(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_UpdateNote_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_async.py new file mode 100644 index 000000000000..38d13497f807 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_async.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateOccurrence +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_UpdateOccurrence_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 grafeas import grafeas_v1 + + +async def sample_update_occurrence(): + # Create a client + client = grafeas_v1.GrafeasAsyncClient() + + # Initialize request argument(s) + request = grafeas_v1.UpdateOccurrenceRequest( + name="name_value", + ) + + # Make the request + response = await client.update_occurrence(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_UpdateOccurrence_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_sync.py new file mode 100644 index 000000000000..af456757fbb8 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_sync.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateOccurrence +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install grafeas + + +# [START containeranalysis_v1_generated_Grafeas_UpdateOccurrence_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 grafeas import grafeas_v1 + + +def sample_update_occurrence(): + # Create a client + client = grafeas_v1.GrafeasClient() + + # Initialize request argument(s) + request = grafeas_v1.UpdateOccurrenceRequest( + name="name_value", + ) + + # Make the request + response = client.update_occurrence(request=request) + + # Handle the response + print(response) + +# [END containeranalysis_v1_generated_Grafeas_UpdateOccurrence_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/snippet_metadata_grafeas.v1.json b/owl-bot-staging/grafeas/v1/samples/generated_samples/snippet_metadata_grafeas.v1.json new file mode 100644 index 000000000000..dc3e1cc8b7ee --- /dev/null +++ b/owl-bot-staging/grafeas/v1/samples/generated_samples/snippet_metadata_grafeas.v1.json @@ -0,0 +1,2353 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "grafeas.v1", + "version": "v1" + } + ], + "language": "PYTHON", + "name": "grafeas", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.batch_create_notes", + "method": { + "fullName": "grafeas.v1.Grafeas.BatchCreateNotes", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "BatchCreateNotes" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.BatchCreateNotesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "notes", + "type": "MutableMapping[str, grafeas.grafeas_v1.types.Note]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.BatchCreateNotesResponse", + "shortName": "batch_create_notes" + }, + "description": "Sample for BatchCreateNotes", + "file": "containeranalysis_v1_generated_grafeas_batch_create_notes_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_BatchCreateNotes_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": "containeranalysis_v1_generated_grafeas_batch_create_notes_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.batch_create_notes", + "method": { + "fullName": "grafeas.v1.Grafeas.BatchCreateNotes", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "BatchCreateNotes" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.BatchCreateNotesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "notes", + "type": "MutableMapping[str, grafeas.grafeas_v1.types.Note]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.BatchCreateNotesResponse", + "shortName": "batch_create_notes" + }, + "description": "Sample for BatchCreateNotes", + "file": "containeranalysis_v1_generated_grafeas_batch_create_notes_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_BatchCreateNotes_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": "containeranalysis_v1_generated_grafeas_batch_create_notes_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.batch_create_occurrences", + "method": { + "fullName": "grafeas.v1.Grafeas.BatchCreateOccurrences", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "BatchCreateOccurrences" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.BatchCreateOccurrencesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "occurrences", + "type": "MutableSequence[grafeas.grafeas_v1.types.Occurrence]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse", + "shortName": "batch_create_occurrences" + }, + "description": "Sample for BatchCreateOccurrences", + "file": "containeranalysis_v1_generated_grafeas_batch_create_occurrences_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_BatchCreateOccurrences_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": "containeranalysis_v1_generated_grafeas_batch_create_occurrences_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.batch_create_occurrences", + "method": { + "fullName": "grafeas.v1.Grafeas.BatchCreateOccurrences", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "BatchCreateOccurrences" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.BatchCreateOccurrencesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "occurrences", + "type": "MutableSequence[grafeas.grafeas_v1.types.Occurrence]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse", + "shortName": "batch_create_occurrences" + }, + "description": "Sample for BatchCreateOccurrences", + "file": "containeranalysis_v1_generated_grafeas_batch_create_occurrences_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_BatchCreateOccurrences_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": "containeranalysis_v1_generated_grafeas_batch_create_occurrences_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.create_note", + "method": { + "fullName": "grafeas.v1.Grafeas.CreateNote", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "CreateNote" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.CreateNoteRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "note_id", + "type": "str" + }, + { + "name": "note", + "type": "grafeas.grafeas_v1.types.Note" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.Note", + "shortName": "create_note" + }, + "description": "Sample for CreateNote", + "file": "containeranalysis_v1_generated_grafeas_create_note_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_CreateNote_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": "containeranalysis_v1_generated_grafeas_create_note_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.create_note", + "method": { + "fullName": "grafeas.v1.Grafeas.CreateNote", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "CreateNote" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.CreateNoteRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "note_id", + "type": "str" + }, + { + "name": "note", + "type": "grafeas.grafeas_v1.types.Note" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.Note", + "shortName": "create_note" + }, + "description": "Sample for CreateNote", + "file": "containeranalysis_v1_generated_grafeas_create_note_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_CreateNote_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": "containeranalysis_v1_generated_grafeas_create_note_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.create_occurrence", + "method": { + "fullName": "grafeas.v1.Grafeas.CreateOccurrence", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "CreateOccurrence" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.CreateOccurrenceRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "occurrence", + "type": "grafeas.grafeas_v1.types.Occurrence" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.Occurrence", + "shortName": "create_occurrence" + }, + "description": "Sample for CreateOccurrence", + "file": "containeranalysis_v1_generated_grafeas_create_occurrence_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_CreateOccurrence_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": "containeranalysis_v1_generated_grafeas_create_occurrence_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.create_occurrence", + "method": { + "fullName": "grafeas.v1.Grafeas.CreateOccurrence", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "CreateOccurrence" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.CreateOccurrenceRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "occurrence", + "type": "grafeas.grafeas_v1.types.Occurrence" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.Occurrence", + "shortName": "create_occurrence" + }, + "description": "Sample for CreateOccurrence", + "file": "containeranalysis_v1_generated_grafeas_create_occurrence_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_CreateOccurrence_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": "containeranalysis_v1_generated_grafeas_create_occurrence_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.delete_note", + "method": { + "fullName": "grafeas.v1.Grafeas.DeleteNote", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "DeleteNote" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.DeleteNoteRequest" + }, + { + "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_note" + }, + "description": "Sample for DeleteNote", + "file": "containeranalysis_v1_generated_grafeas_delete_note_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_DeleteNote_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": "containeranalysis_v1_generated_grafeas_delete_note_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.delete_note", + "method": { + "fullName": "grafeas.v1.Grafeas.DeleteNote", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "DeleteNote" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.DeleteNoteRequest" + }, + { + "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_note" + }, + "description": "Sample for DeleteNote", + "file": "containeranalysis_v1_generated_grafeas_delete_note_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_DeleteNote_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": "containeranalysis_v1_generated_grafeas_delete_note_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.delete_occurrence", + "method": { + "fullName": "grafeas.v1.Grafeas.DeleteOccurrence", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "DeleteOccurrence" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.DeleteOccurrenceRequest" + }, + { + "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_occurrence" + }, + "description": "Sample for DeleteOccurrence", + "file": "containeranalysis_v1_generated_grafeas_delete_occurrence_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_DeleteOccurrence_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": "containeranalysis_v1_generated_grafeas_delete_occurrence_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.delete_occurrence", + "method": { + "fullName": "grafeas.v1.Grafeas.DeleteOccurrence", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "DeleteOccurrence" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.DeleteOccurrenceRequest" + }, + { + "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_occurrence" + }, + "description": "Sample for DeleteOccurrence", + "file": "containeranalysis_v1_generated_grafeas_delete_occurrence_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_DeleteOccurrence_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": "containeranalysis_v1_generated_grafeas_delete_occurrence_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.get_note", + "method": { + "fullName": "grafeas.v1.Grafeas.GetNote", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "GetNote" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.GetNoteRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.Note", + "shortName": "get_note" + }, + "description": "Sample for GetNote", + "file": "containeranalysis_v1_generated_grafeas_get_note_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_GetNote_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": "containeranalysis_v1_generated_grafeas_get_note_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.get_note", + "method": { + "fullName": "grafeas.v1.Grafeas.GetNote", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "GetNote" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.GetNoteRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.Note", + "shortName": "get_note" + }, + "description": "Sample for GetNote", + "file": "containeranalysis_v1_generated_grafeas_get_note_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_GetNote_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": "containeranalysis_v1_generated_grafeas_get_note_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.get_occurrence_note", + "method": { + "fullName": "grafeas.v1.Grafeas.GetOccurrenceNote", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "GetOccurrenceNote" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.GetOccurrenceNoteRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.Note", + "shortName": "get_occurrence_note" + }, + "description": "Sample for GetOccurrenceNote", + "file": "containeranalysis_v1_generated_grafeas_get_occurrence_note_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_GetOccurrenceNote_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": "containeranalysis_v1_generated_grafeas_get_occurrence_note_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.get_occurrence_note", + "method": { + "fullName": "grafeas.v1.Grafeas.GetOccurrenceNote", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "GetOccurrenceNote" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.GetOccurrenceNoteRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.Note", + "shortName": "get_occurrence_note" + }, + "description": "Sample for GetOccurrenceNote", + "file": "containeranalysis_v1_generated_grafeas_get_occurrence_note_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_GetOccurrenceNote_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": "containeranalysis_v1_generated_grafeas_get_occurrence_note_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.get_occurrence", + "method": { + "fullName": "grafeas.v1.Grafeas.GetOccurrence", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "GetOccurrence" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.GetOccurrenceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.Occurrence", + "shortName": "get_occurrence" + }, + "description": "Sample for GetOccurrence", + "file": "containeranalysis_v1_generated_grafeas_get_occurrence_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_GetOccurrence_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": "containeranalysis_v1_generated_grafeas_get_occurrence_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.get_occurrence", + "method": { + "fullName": "grafeas.v1.Grafeas.GetOccurrence", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "GetOccurrence" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.GetOccurrenceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.types.Occurrence", + "shortName": "get_occurrence" + }, + "description": "Sample for GetOccurrence", + "file": "containeranalysis_v1_generated_grafeas_get_occurrence_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_GetOccurrence_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": "containeranalysis_v1_generated_grafeas_get_occurrence_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.list_note_occurrences", + "method": { + "fullName": "grafeas.v1.Grafeas.ListNoteOccurrences", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "ListNoteOccurrences" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.ListNoteOccurrencesRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "filter", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesAsyncPager", + "shortName": "list_note_occurrences" + }, + "description": "Sample for ListNoteOccurrences", + "file": "containeranalysis_v1_generated_grafeas_list_note_occurrences_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_ListNoteOccurrences_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": "containeranalysis_v1_generated_grafeas_list_note_occurrences_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.list_note_occurrences", + "method": { + "fullName": "grafeas.v1.Grafeas.ListNoteOccurrences", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "ListNoteOccurrences" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.ListNoteOccurrencesRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "filter", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesPager", + "shortName": "list_note_occurrences" + }, + "description": "Sample for ListNoteOccurrences", + "file": "containeranalysis_v1_generated_grafeas_list_note_occurrences_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_ListNoteOccurrences_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": "containeranalysis_v1_generated_grafeas_list_note_occurrences_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.list_notes", + "method": { + "fullName": "grafeas.v1.Grafeas.ListNotes", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "ListNotes" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.ListNotesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "filter", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListNotesAsyncPager", + "shortName": "list_notes" + }, + "description": "Sample for ListNotes", + "file": "containeranalysis_v1_generated_grafeas_list_notes_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_ListNotes_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": "containeranalysis_v1_generated_grafeas_list_notes_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.list_notes", + "method": { + "fullName": "grafeas.v1.Grafeas.ListNotes", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "ListNotes" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.ListNotesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "filter", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListNotesPager", + "shortName": "list_notes" + }, + "description": "Sample for ListNotes", + "file": "containeranalysis_v1_generated_grafeas_list_notes_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_ListNotes_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": "containeranalysis_v1_generated_grafeas_list_notes_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.list_occurrences", + "method": { + "fullName": "grafeas.v1.Grafeas.ListOccurrences", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "ListOccurrences" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.ListOccurrencesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "filter", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesAsyncPager", + "shortName": "list_occurrences" + }, + "description": "Sample for ListOccurrences", + "file": "containeranalysis_v1_generated_grafeas_list_occurrences_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_ListOccurrences_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": "containeranalysis_v1_generated_grafeas_list_occurrences_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.list_occurrences", + "method": { + "fullName": "grafeas.v1.Grafeas.ListOccurrences", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "ListOccurrences" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.ListOccurrencesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "filter", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesPager", + "shortName": "list_occurrences" + }, + "description": "Sample for ListOccurrences", + "file": "containeranalysis_v1_generated_grafeas_list_occurrences_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_ListOccurrences_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": "containeranalysis_v1_generated_grafeas_list_occurrences_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.update_note", + "method": { + "fullName": "grafeas.v1.Grafeas.UpdateNote", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "UpdateNote" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.UpdateNoteRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "note", + "type": "grafeas.grafeas_v1.types.Note" + }, + { + "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": "grafeas.grafeas_v1.types.Note", + "shortName": "update_note" + }, + "description": "Sample for UpdateNote", + "file": "containeranalysis_v1_generated_grafeas_update_note_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_UpdateNote_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": "containeranalysis_v1_generated_grafeas_update_note_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.update_note", + "method": { + "fullName": "grafeas.v1.Grafeas.UpdateNote", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "UpdateNote" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.UpdateNoteRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "note", + "type": "grafeas.grafeas_v1.types.Note" + }, + { + "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": "grafeas.grafeas_v1.types.Note", + "shortName": "update_note" + }, + "description": "Sample for UpdateNote", + "file": "containeranalysis_v1_generated_grafeas_update_note_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_UpdateNote_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": "containeranalysis_v1_generated_grafeas_update_note_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", + "shortName": "GrafeasAsyncClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.update_occurrence", + "method": { + "fullName": "grafeas.v1.Grafeas.UpdateOccurrence", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "UpdateOccurrence" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.UpdateOccurrenceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "occurrence", + "type": "grafeas.grafeas_v1.types.Occurrence" + }, + { + "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": "grafeas.grafeas_v1.types.Occurrence", + "shortName": "update_occurrence" + }, + "description": "Sample for UpdateOccurrence", + "file": "containeranalysis_v1_generated_grafeas_update_occurrence_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_UpdateOccurrence_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": "containeranalysis_v1_generated_grafeas_update_occurrence_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "grafeas.grafeas_v1.GrafeasClient", + "shortName": "GrafeasClient" + }, + "fullName": "grafeas.grafeas_v1.GrafeasClient.update_occurrence", + "method": { + "fullName": "grafeas.v1.Grafeas.UpdateOccurrence", + "service": { + "fullName": "grafeas.v1.Grafeas", + "shortName": "Grafeas" + }, + "shortName": "UpdateOccurrence" + }, + "parameters": [ + { + "name": "request", + "type": "grafeas.grafeas_v1.types.UpdateOccurrenceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "occurrence", + "type": "grafeas.grafeas_v1.types.Occurrence" + }, + { + "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": "grafeas.grafeas_v1.types.Occurrence", + "shortName": "update_occurrence" + }, + "description": "Sample for UpdateOccurrence", + "file": "containeranalysis_v1_generated_grafeas_update_occurrence_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "containeranalysis_v1_generated_Grafeas_UpdateOccurrence_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": "containeranalysis_v1_generated_grafeas_update_occurrence_sync.py" + } + ] +} diff --git a/owl-bot-staging/grafeas/v1/scripts/fixup_grafeas_v1_keywords.py b/owl-bot-staging/grafeas/v1/scripts/fixup_grafeas_v1_keywords.py new file mode 100644 index 000000000000..78bae6683cc8 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/scripts/fixup_grafeas_v1_keywords.py @@ -0,0 +1,189 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 grafeasCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'batch_create_notes': ('parent', 'notes', ), + 'batch_create_occurrences': ('parent', 'occurrences', ), + 'create_note': ('parent', 'note_id', 'note', ), + 'create_occurrence': ('parent', 'occurrence', ), + 'delete_note': ('name', ), + 'delete_occurrence': ('name', ), + 'get_note': ('name', ), + 'get_occurrence': ('name', ), + 'get_occurrence_note': ('name', ), + 'list_note_occurrences': ('name', 'filter', 'page_size', 'page_token', ), + 'list_notes': ('parent', 'filter', 'page_size', 'page_token', ), + 'list_occurrences': ('parent', 'filter', 'page_size', 'page_token', ), + 'update_note': ('name', 'note', 'update_mask', ), + 'update_occurrence': ('name', 'occurrence', 'update_mask', ), + } + + def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: + try: + key = original.func.attr.value + kword_params = self.METHOD_TO_PARAMS[key] + except (AttributeError, KeyError): + # Either not a method from the API or too convoluted to be sure. + return updated + + # If the existing code is valid, keyword args come after positional args. + # Therefore, all positional args must map to the first parameters. + args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) + if any(k.keyword.value == "request" for k in kwargs): + # We've already fixed this file, don't fix it again. + return updated + + kwargs, ctrl_kwargs = partition( + lambda a: a.keyword.value not in self.CTRL_PARAMS, + kwargs + ) + + args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] + ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) + for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) + + request_arg = cst.Arg( + value=cst.Dict([ + cst.DictElement( + cst.SimpleString("'{}'".format(name)), +cst.Element(value=arg.value) + ) + # Note: the args + kwargs looks silly, but keep in mind that + # the control parameters had to be stripped out, and that + # those could have been passed positionally or by keyword. + for name, arg in zip(kword_params, args + kwargs)]), + keyword=cst.Name("request") + ) + + return updated.with_changes( + args=[request_arg] + ctrl_kwargs + ) + + +def fix_files( + in_dir: pathlib.Path, + out_dir: pathlib.Path, + *, + transformer=grafeasCallTransformer(), +): + """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 grafeas 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/grafeas/v1/setup.py b/owl-bot-staging/grafeas/v1/setup.py new file mode 100644 index 000000000000..42545da2ab4f --- /dev/null +++ b/owl-bot-staging/grafeas/v1/setup.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 re + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = 'grafeas' + + +description = "Grafeas API client library" + +version = None + +with open(os.path.join(package_root, 'grafeas/grafeas/gapic_version.py')) as fp: + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + assert (len(version_candidates) == 1) + version = version_candidates[0] + +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.1, <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.*", + # Exclude incompatible versions of `google-auth` + # See https://github.com/googleapis/google-cloud-python/issues/12364 + "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", + "proto-plus >= 1.22.3, <2.0.0dev", + "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", + "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", +] +extras = { +} +url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/grafeas" + +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.find_namespace_packages() + if package.startswith("grafeas") +] + +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", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + install_requires=dependencies, + extras_require=extras, + include_package_data=True, + zip_safe=False, +) diff --git a/owl-bot-staging/grafeas/v1/testing/constraints-3.10.txt b/owl-bot-staging/grafeas/v1/testing/constraints-3.10.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/testing/constraints-3.10.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/grafeas/v1/testing/constraints-3.11.txt b/owl-bot-staging/grafeas/v1/testing/constraints-3.11.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/testing/constraints-3.11.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/grafeas/v1/testing/constraints-3.12.txt b/owl-bot-staging/grafeas/v1/testing/constraints-3.12.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/testing/constraints-3.12.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/grafeas/v1/testing/constraints-3.13.txt b/owl-bot-staging/grafeas/v1/testing/constraints-3.13.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/testing/constraints-3.13.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/grafeas/v1/testing/constraints-3.7.txt b/owl-bot-staging/grafeas/v1/testing/constraints-3.7.txt new file mode 100644 index 000000000000..fc812592b0ee --- /dev/null +++ b/owl-bot-staging/grafeas/v1/testing/constraints-3.7.txt @@ -0,0 +1,10 @@ +# 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.1 +google-auth==2.14.1 +proto-plus==1.22.3 +protobuf==3.20.2 diff --git a/owl-bot-staging/grafeas/v1/testing/constraints-3.8.txt b/owl-bot-staging/grafeas/v1/testing/constraints-3.8.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/testing/constraints-3.8.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/grafeas/v1/testing/constraints-3.9.txt b/owl-bot-staging/grafeas/v1/testing/constraints-3.9.txt new file mode 100644 index 000000000000..ed7f9aed2559 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/testing/constraints-3.9.txt @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +proto-plus +protobuf diff --git a/owl-bot-staging/grafeas/v1/tests/__init__.py b/owl-bot-staging/grafeas/v1/tests/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/tests/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/grafeas/v1/tests/unit/__init__.py b/owl-bot-staging/grafeas/v1/tests/unit/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/tests/unit/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/grafeas/v1/tests/unit/gapic/__init__.py b/owl-bot-staging/grafeas/v1/tests/unit/gapic/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/tests/unit/gapic/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/grafeas/v1/tests/unit/gapic/grafeas_v1/__init__.py b/owl-bot-staging/grafeas/v1/tests/unit/gapic/grafeas_v1/__init__.py new file mode 100644 index 000000000000..7b3de3117f38 --- /dev/null +++ b/owl-bot-staging/grafeas/v1/tests/unit/gapic/grafeas_v1/__init__.py @@ -0,0 +1,16 @@ + +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/grafeas/v1/tests/unit/gapic/grafeas_v1/test_grafeas.py b/owl-bot-staging/grafeas/v1/tests/unit/gapic/grafeas_v1/test_grafeas.py new file mode 100644 index 000000000000..9d115bd76b9d --- /dev/null +++ b/owl-bot-staging/grafeas/v1/tests/unit/gapic/grafeas_v1/test_grafeas.py @@ -0,0 +1,11984 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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, AsyncIterable +from google.protobuf import json_format +import json +import math +import pytest +from google.api_core import api_core_version +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 + +try: + from google.auth.aio import credentials as ga_credentials_async + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +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.api_core import retry as retries +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.oauth2 import service_account +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from grafeas.grafeas_v1.services.grafeas import GrafeasAsyncClient +from grafeas.grafeas_v1.services.grafeas import GrafeasClient +from grafeas.grafeas_v1.services.grafeas import pagers +from grafeas.grafeas_v1.services.grafeas import transports +from grafeas.grafeas_v1.types import attestation +from grafeas.grafeas_v1.types import build +from grafeas.grafeas_v1.types import common +from grafeas.grafeas_v1.types import compliance +from grafeas.grafeas_v1.types import cvss +from grafeas.grafeas_v1.types import deployment +from grafeas.grafeas_v1.types import discovery +from grafeas.grafeas_v1.types import dsse_attestation +from grafeas.grafeas_v1.types import grafeas +from grafeas.grafeas_v1.types import image +from grafeas.grafeas_v1.types import intoto_provenance +from grafeas.grafeas_v1.types import intoto_statement +from grafeas.grafeas_v1.types import package +from grafeas.grafeas_v1.types import provenance +from grafeas.grafeas_v1.types import sbom +from grafeas.grafeas_v1.types import severity +from grafeas.grafeas_v1.types import slsa_provenance +from grafeas.grafeas_v1.types import slsa_provenance_zero_two +from grafeas.grafeas_v1.types import upgrade +from grafeas.grafeas_v1.types import vex +from grafeas.grafeas_v1.types import vulnerability +import google.auth + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + +# 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 + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return "test.{UNIVERSE_DOMAIN}" if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) else client._DEFAULT_ENDPOINT_TEMPLATE + + +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 GrafeasClient._get_default_mtls_endpoint(None) is None + assert GrafeasClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert GrafeasClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert GrafeasClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert GrafeasClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert GrafeasClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + +def test__read_environment_variables(): + assert GrafeasClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert GrafeasClient._read_environment_variables() == (True, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert GrafeasClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError) as excinfo: + GrafeasClient._read_environment_variables() + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert GrafeasClient._read_environment_variables() == (False, "never", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert GrafeasClient._read_environment_variables() == (False, "always", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert GrafeasClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + GrafeasClient._read_environment_variables() + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert GrafeasClient._read_environment_variables() == (False, "auto", "foo.com") + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert GrafeasClient._get_client_cert_source(None, False) is None + assert GrafeasClient._get_client_cert_source(mock_provided_cert_source, False) is None + assert GrafeasClient._get_client_cert_source(mock_provided_cert_source, True) == mock_provided_cert_source + + 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_default_cert_source): + assert GrafeasClient._get_client_cert_source(None, True) is mock_default_cert_source + assert GrafeasClient._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source + +@mock.patch.object(GrafeasClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasClient)) +@mock.patch.object(GrafeasAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasAsyncClient)) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = GrafeasClient._DEFAULT_UNIVERSE + default_endpoint = GrafeasClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) + mock_universe = "bar.com" + mock_endpoint = GrafeasClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) + + assert GrafeasClient._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override + assert GrafeasClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == GrafeasClient.DEFAULT_MTLS_ENDPOINT + assert GrafeasClient._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint + assert GrafeasClient._get_api_endpoint(None, None, default_universe, "always") == GrafeasClient.DEFAULT_MTLS_ENDPOINT + assert GrafeasClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == GrafeasClient.DEFAULT_MTLS_ENDPOINT + assert GrafeasClient._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint + assert GrafeasClient._get_api_endpoint(None, None, default_universe, "never") == default_endpoint + + with pytest.raises(MutualTLSChannelError) as excinfo: + GrafeasClient._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto") + assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com." + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert GrafeasClient._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain + assert GrafeasClient._get_universe_domain(None, universe_domain_env) == universe_domain_env + assert GrafeasClient._get_universe_domain(None, None) == GrafeasClient._DEFAULT_UNIVERSE + + with pytest.raises(ValueError) as excinfo: + GrafeasClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (GrafeasClient, transports.GrafeasGrpcTransport, "grpc"), + (GrafeasClient, transports.GrafeasRestTransport, "rest"), +]) +def test__validate_universe_domain(client_class, transport_class, transport_name): + client = client_class( + transport=transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + ) + assert client._validate_universe_domain() == True + + # Test the case when universe is already validated. + assert client._validate_universe_domain() == True + + if transport_name == "grpc": + # Test the case where credentials are provided by the + # `local_channel_credentials`. The default universes in both match. + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + client = client_class(transport=transport_class(channel=channel)) + assert client._validate_universe_domain() == True + + # Test the case where credentials do not exist: e.g. a transport is provided + # with no credentials. Validation should still succeed because there is no + # mismatch with non-existent credentials. + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + transport=transport_class(channel=channel) + transport._credentials = None + client = client_class(transport=transport) + assert client._validate_universe_domain() == True + + # TODO: This is needed to cater for older versions of google-auth + # Make this test unconditional once the minimum supported version of + # google-auth becomes 2.23.0 or higher. + google_auth_major, google_auth_minor = [int(part) for part in google.auth.__version__.split(".")[0:2]] + if google_auth_major > 2 or (google_auth_major == 2 and google_auth_minor >= 23): + credentials = ga_credentials.AnonymousCredentials() + credentials._universe_domain = "foo.com" + # Test the case when there is a universe mismatch from the credentials. + client = client_class( + transport=transport_class(credentials=credentials) + ) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert str(excinfo.value) == "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (foo.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + + # Test the case when there is a universe mismatch from the client. + # + # TODO: Make this test unconditional once the minimum supported version of + # google-api-core becomes 2.15.0 or higher. + api_core_major, api_core_minor = [int(part) for part in api_core_version.__version__.split(".")[0:2]] + if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 15): + client = client_class(client_options={"universe_domain": "bar.com"}, transport=transport_class(credentials=ga_credentials.AnonymousCredentials(),)) + with pytest.raises(ValueError) as excinfo: + client._validate_universe_domain() + assert str(excinfo.value) == "The configured universe domain (bar.com) does not match the universe domain found in the credentials (googleapis.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." + + # Test that ValueError is raised if universe_domain is provided via client options and credentials is None + with pytest.raises(ValueError): + client._compare_universes("foo.bar", None) + + +@pytest.mark.parametrize("client_class,transport_name", [ + (GrafeasClient, "grpc"), + (GrafeasAsyncClient, "grpc_asyncio"), + (GrafeasClient, "rest"), +]) +def test_grafeas_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 == ( + 'containeranalysis.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://containeranalysis.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.GrafeasGrpcTransport, "grpc"), + (transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.GrafeasRestTransport, "rest"), +]) +def test_grafeas_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", [ + (GrafeasClient, "grpc"), + (GrafeasAsyncClient, "grpc_asyncio"), + (GrafeasClient, "rest"), +]) +def test_grafeas_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 == ( + 'containeranalysis.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://containeranalysis.googleapis.com' + ) + + +def test_grafeas_client_get_transport_class(): + transport = GrafeasClient.get_transport_class() + available_transports = [ + transports.GrafeasGrpcTransport, + transports.GrafeasRestTransport, + ] + assert transport in available_transports + + transport = GrafeasClient.get_transport_class("grpc") + assert transport == transports.GrafeasGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (GrafeasClient, transports.GrafeasGrpcTransport, "grpc"), + (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio"), + (GrafeasClient, transports.GrafeasRestTransport, "rest"), +]) +@mock.patch.object(GrafeasClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasClient)) +@mock.patch.object(GrafeasAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasAsyncClient)) +def test_grafeas_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(GrafeasClient, '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(GrafeasClient, '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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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) as excinfo: + client = client_class(transport=transport_name) + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + # 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) as excinfo: + client = client_class(transport=transport_name) + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + + # 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + 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", [ + (GrafeasClient, transports.GrafeasGrpcTransport, "grpc", "true"), + (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (GrafeasClient, transports.GrafeasGrpcTransport, "grpc", "false"), + (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (GrafeasClient, transports.GrafeasRestTransport, "rest", "true"), + (GrafeasClient, transports.GrafeasRestTransport, "rest", "false"), +]) +@mock.patch.object(GrafeasClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasClient)) +@mock.patch.object(GrafeasAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_grafeas_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) + 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) + 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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", [ + GrafeasClient, GrafeasAsyncClient +]) +@mock.patch.object(GrafeasClient, "DEFAULT_ENDPOINT", modify_default_endpoint(GrafeasClient)) +@mock.patch.object(GrafeasAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(GrafeasAsyncClient)) +def test_grafeas_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 + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + # 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) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + +@pytest.mark.parametrize("client_class", [ + GrafeasClient, GrafeasAsyncClient +]) +@mock.patch.object(GrafeasClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasClient)) +@mock.patch.object(GrafeasAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasAsyncClient)) +def test_grafeas_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = GrafeasClient._DEFAULT_UNIVERSE + default_endpoint = GrafeasClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) + mock_universe = "bar.com" + mock_endpoint = GrafeasClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel"): + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=api_override) + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + else: + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == (mock_endpoint if universe_exists else default_endpoint) + assert client.universe_domain == (mock_universe if universe_exists else default_universe) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (GrafeasClient, transports.GrafeasGrpcTransport, "grpc"), + (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio"), + (GrafeasClient, transports.GrafeasRestTransport, "rest"), +]) +def test_grafeas_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + 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", [ + (GrafeasClient, transports.GrafeasGrpcTransport, "grpc", grpc_helpers), + (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (GrafeasClient, transports.GrafeasRestTransport, "rest", None), +]) +def test_grafeas_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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_grafeas_client_client_options_from_dict(): + with mock.patch('grafeas.grafeas_v1.services.grafeas.transports.GrafeasGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = GrafeasClient( + 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", [ + (GrafeasClient, transports.GrafeasGrpcTransport, "grpc", grpc_helpers), + (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_grafeas_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_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( + "containeranalysis.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( +), + scopes=None, + default_host="containeranalysis.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + grafeas.GetOccurrenceRequest, + dict, +]) +def test_get_occurrence(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Occurrence( + name='name_value', + resource_uri='resource_uri_value', + note_name='note_name_value', + kind=common.NoteKind.VULNERABILITY, + remediation='remediation_value', + ) + response = client.get_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.GetOccurrenceRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Occurrence) + assert response.name == 'name_value' + assert response.resource_uri == 'resource_uri_value' + assert response.note_name == 'note_name_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.remediation == 'remediation_value' + + +def test_get_occurrence_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.GetOccurrenceRequest( + name='name_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.get_occurrence(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.GetOccurrenceRequest( + name='name_value', + ) + +def test_get_occurrence_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_occurrence in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.get_occurrence] = mock_rpc + request = {} + client.get_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_get_occurrence_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.get_occurrence in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.get_occurrence] = mock_rpc + + request = {} + await client.get_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_get_occurrence_async(transport: str = 'grpc_asyncio', request_type=grafeas.GetOccurrenceRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence( + name='name_value', + resource_uri='resource_uri_value', + note_name='note_name_value', + kind=common.NoteKind.VULNERABILITY, + remediation='remediation_value', + )) + response = await client.get_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.GetOccurrenceRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Occurrence) + assert response.name == 'name_value' + assert response.resource_uri == 'resource_uri_value' + assert response.note_name == 'note_name_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.remediation == 'remediation_value' + + +@pytest.mark.asyncio +async def test_get_occurrence_async_from_dict(): + await test_get_occurrence_async(request_type=dict) + +def test_get_occurrence_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.GetOccurrenceRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence), + '__call__') as call: + call.return_value = grafeas.Occurrence() + client.get_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_occurrence_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.GetOccurrenceRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence()) + await client.get_occurrence(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_occurrence_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Occurrence() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_occurrence( + 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_occurrence_flattened_error(): + client = GrafeasClient( + 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_occurrence( + grafeas.GetOccurrenceRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_occurrence_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Occurrence() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_occurrence( + 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_occurrence_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_occurrence( + grafeas.GetOccurrenceRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + grafeas.ListOccurrencesRequest, + dict, +]) +def test_list_occurrences(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.ListOccurrencesResponse( + next_page_token='next_page_token_value', + ) + response = client.list_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.ListOccurrencesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListOccurrencesPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_occurrences_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.ListOccurrencesRequest( + parent='parent_value', + filter='filter_value', + page_token='page_token_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_occurrences), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.list_occurrences(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.ListOccurrencesRequest( + parent='parent_value', + filter='filter_value', + page_token='page_token_value', + ) + +def test_list_occurrences_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_occurrences in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.list_occurrences] = mock_rpc + request = {} + client.list_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_occurrences(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_occurrences_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.list_occurrences in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.list_occurrences] = mock_rpc + + request = {} + await client.list_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_occurrences(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_occurrences_async(transport: str = 'grpc_asyncio', request_type=grafeas.ListOccurrencesRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListOccurrencesResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.ListOccurrencesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListOccurrencesAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_occurrences_async_from_dict(): + await test_list_occurrences_async(request_type=dict) + +def test_list_occurrences_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.ListOccurrencesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_occurrences), + '__call__') as call: + call.return_value = grafeas.ListOccurrencesResponse() + client.list_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_occurrences_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.ListOccurrencesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_occurrences), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListOccurrencesResponse()) + await client.list_occurrences(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_occurrences_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.ListOccurrencesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_occurrences( + parent='parent_value', + filter='filter_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].filter + mock_val = 'filter_value' + assert arg == mock_val + + +def test_list_occurrences_flattened_error(): + client = GrafeasClient( + 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_occurrences( + grafeas.ListOccurrencesRequest(), + parent='parent_value', + filter='filter_value', + ) + +@pytest.mark.asyncio +async def test_list_occurrences_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.ListOccurrencesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListOccurrencesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_occurrences( + parent='parent_value', + filter='filter_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].filter + mock_val = 'filter_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_occurrences_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_occurrences( + grafeas.ListOccurrencesRequest(), + parent='parent_value', + filter='filter_value', + ) + + +def test_list_occurrences_pager(transport_name: str = "grpc"): + client = GrafeasClient( + 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_occurrences), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + next_page_token='abc', + ), + grafeas.ListOccurrencesResponse( + occurrences=[], + next_page_token='def', + ), + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + ], + next_page_token='ghi', + ), + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_occurrences(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, grafeas.Occurrence) + for i in results) +def test_list_occurrences_pages(transport_name: str = "grpc"): + client = GrafeasClient( + 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_occurrences), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + next_page_token='abc', + ), + grafeas.ListOccurrencesResponse( + occurrences=[], + next_page_token='def', + ), + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + ], + next_page_token='ghi', + ), + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + ), + RuntimeError, + ) + pages = list(client.list_occurrences(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_occurrences_async_pager(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_occurrences), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + next_page_token='abc', + ), + grafeas.ListOccurrencesResponse( + occurrences=[], + next_page_token='def', + ), + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + ], + next_page_token='ghi', + ), + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_occurrences(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, grafeas.Occurrence) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_occurrences_async_pages(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_occurrences), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + next_page_token='abc', + ), + grafeas.ListOccurrencesResponse( + occurrences=[], + next_page_token='def', + ), + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + ], + next_page_token='ghi', + ), + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + ), + 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_occurrences(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", [ + grafeas.DeleteOccurrenceRequest, + dict, +]) +def test_delete_occurrence(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.DeleteOccurrenceRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_occurrence_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.DeleteOccurrenceRequest( + name='name_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_occurrence), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.delete_occurrence(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.DeleteOccurrenceRequest( + name='name_value', + ) + +def test_delete_occurrence_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.delete_occurrence in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.delete_occurrence] = mock_rpc + request = {} + client.delete_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.delete_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_delete_occurrence_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.delete_occurrence in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.delete_occurrence] = mock_rpc + + request = {} + await client.delete_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.delete_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_delete_occurrence_async(transport: str = 'grpc_asyncio', request_type=grafeas.DeleteOccurrenceRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.DeleteOccurrenceRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_occurrence_async_from_dict(): + await test_delete_occurrence_async(request_type=dict) + +def test_delete_occurrence_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.DeleteOccurrenceRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_occurrence), + '__call__') as call: + call.return_value = None + client.delete_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_occurrence_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.DeleteOccurrenceRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_occurrence), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_occurrence(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_occurrence_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_occurrence), + '__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_occurrence( + 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_occurrence_flattened_error(): + client = GrafeasClient( + 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_occurrence( + grafeas.DeleteOccurrenceRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_occurrence_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_occurrence), + '__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_occurrence( + 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_occurrence_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_occurrence( + grafeas.DeleteOccurrenceRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + grafeas.CreateOccurrenceRequest, + dict, +]) +def test_create_occurrence(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Occurrence( + name='name_value', + resource_uri='resource_uri_value', + note_name='note_name_value', + kind=common.NoteKind.VULNERABILITY, + remediation='remediation_value', + ) + response = client.create_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.CreateOccurrenceRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Occurrence) + assert response.name == 'name_value' + assert response.resource_uri == 'resource_uri_value' + assert response.note_name == 'note_name_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.remediation == 'remediation_value' + + +def test_create_occurrence_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.CreateOccurrenceRequest( + parent='parent_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_occurrence), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.create_occurrence(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.CreateOccurrenceRequest( + parent='parent_value', + ) + +def test_create_occurrence_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_occurrence in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.create_occurrence] = mock_rpc + request = {} + client.create_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_create_occurrence_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.create_occurrence in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.create_occurrence] = mock_rpc + + request = {} + await client.create_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.create_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_create_occurrence_async(transport: str = 'grpc_asyncio', request_type=grafeas.CreateOccurrenceRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence( + name='name_value', + resource_uri='resource_uri_value', + note_name='note_name_value', + kind=common.NoteKind.VULNERABILITY, + remediation='remediation_value', + )) + response = await client.create_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.CreateOccurrenceRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Occurrence) + assert response.name == 'name_value' + assert response.resource_uri == 'resource_uri_value' + assert response.note_name == 'note_name_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.remediation == 'remediation_value' + + +@pytest.mark.asyncio +async def test_create_occurrence_async_from_dict(): + await test_create_occurrence_async(request_type=dict) + +def test_create_occurrence_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.CreateOccurrenceRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_occurrence), + '__call__') as call: + call.return_value = grafeas.Occurrence() + client.create_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_occurrence_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.CreateOccurrenceRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_occurrence), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence()) + await client.create_occurrence(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_occurrence_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Occurrence() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_occurrence( + parent='parent_value', + occurrence=grafeas.Occurrence(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].occurrence + mock_val = grafeas.Occurrence(name='name_value') + assert arg == mock_val + + +def test_create_occurrence_flattened_error(): + client = GrafeasClient( + 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_occurrence( + grafeas.CreateOccurrenceRequest(), + parent='parent_value', + occurrence=grafeas.Occurrence(name='name_value'), + ) + +@pytest.mark.asyncio +async def test_create_occurrence_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Occurrence() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_occurrence( + parent='parent_value', + occurrence=grafeas.Occurrence(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].occurrence + mock_val = grafeas.Occurrence(name='name_value') + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_occurrence_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_occurrence( + grafeas.CreateOccurrenceRequest(), + parent='parent_value', + occurrence=grafeas.Occurrence(name='name_value'), + ) + + +@pytest.mark.parametrize("request_type", [ + grafeas.BatchCreateOccurrencesRequest, + dict, +]) +def test_batch_create_occurrences(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_create_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.BatchCreateOccurrencesResponse( + ) + response = client.batch_create_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.BatchCreateOccurrencesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.BatchCreateOccurrencesResponse) + + +def test_batch_create_occurrences_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.BatchCreateOccurrencesRequest( + parent='parent_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_occurrences), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.batch_create_occurrences(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.BatchCreateOccurrencesRequest( + parent='parent_value', + ) + +def test_batch_create_occurrences_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.batch_create_occurrences in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.batch_create_occurrences] = mock_rpc + request = {} + client.batch_create_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_create_occurrences(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_batch_create_occurrences_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.batch_create_occurrences in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.batch_create_occurrences] = mock_rpc + + request = {} + await client.batch_create_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.batch_create_occurrences(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_batch_create_occurrences_async(transport: str = 'grpc_asyncio', request_type=grafeas.BatchCreateOccurrencesRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_create_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateOccurrencesResponse( + )) + response = await client.batch_create_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.BatchCreateOccurrencesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.BatchCreateOccurrencesResponse) + + +@pytest.mark.asyncio +async def test_batch_create_occurrences_async_from_dict(): + await test_batch_create_occurrences_async(request_type=dict) + +def test_batch_create_occurrences_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.BatchCreateOccurrencesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_occurrences), + '__call__') as call: + call.return_value = grafeas.BatchCreateOccurrencesResponse() + client.batch_create_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_batch_create_occurrences_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.BatchCreateOccurrencesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_occurrences), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateOccurrencesResponse()) + await client.batch_create_occurrences(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_batch_create_occurrences_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.BatchCreateOccurrencesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.batch_create_occurrences( + parent='parent_value', + occurrences=[grafeas.Occurrence(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].occurrences + mock_val = [grafeas.Occurrence(name='name_value')] + assert arg == mock_val + + +def test_batch_create_occurrences_flattened_error(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_create_occurrences( + grafeas.BatchCreateOccurrencesRequest(), + parent='parent_value', + occurrences=[grafeas.Occurrence(name='name_value')], + ) + +@pytest.mark.asyncio +async def test_batch_create_occurrences_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.BatchCreateOccurrencesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateOccurrencesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.batch_create_occurrences( + parent='parent_value', + occurrences=[grafeas.Occurrence(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].occurrences + mock_val = [grafeas.Occurrence(name='name_value')] + assert arg == mock_val + +@pytest.mark.asyncio +async def test_batch_create_occurrences_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.batch_create_occurrences( + grafeas.BatchCreateOccurrencesRequest(), + parent='parent_value', + occurrences=[grafeas.Occurrence(name='name_value')], + ) + + +@pytest.mark.parametrize("request_type", [ + grafeas.UpdateOccurrenceRequest, + dict, +]) +def test_update_occurrence(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Occurrence( + name='name_value', + resource_uri='resource_uri_value', + note_name='note_name_value', + kind=common.NoteKind.VULNERABILITY, + remediation='remediation_value', + ) + response = client.update_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.UpdateOccurrenceRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Occurrence) + assert response.name == 'name_value' + assert response.resource_uri == 'resource_uri_value' + assert response.note_name == 'note_name_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.remediation == 'remediation_value' + + +def test_update_occurrence_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.UpdateOccurrenceRequest( + name='name_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_occurrence), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.update_occurrence(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.UpdateOccurrenceRequest( + name='name_value', + ) + +def test_update_occurrence_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_occurrence in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.update_occurrence] = mock_rpc + request = {} + client.update_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_update_occurrence_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.update_occurrence in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.update_occurrence] = mock_rpc + + request = {} + await client.update_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.update_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_update_occurrence_async(transport: str = 'grpc_asyncio', request_type=grafeas.UpdateOccurrenceRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence( + name='name_value', + resource_uri='resource_uri_value', + note_name='note_name_value', + kind=common.NoteKind.VULNERABILITY, + remediation='remediation_value', + )) + response = await client.update_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.UpdateOccurrenceRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Occurrence) + assert response.name == 'name_value' + assert response.resource_uri == 'resource_uri_value' + assert response.note_name == 'note_name_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.remediation == 'remediation_value' + + +@pytest.mark.asyncio +async def test_update_occurrence_async_from_dict(): + await test_update_occurrence_async(request_type=dict) + +def test_update_occurrence_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.UpdateOccurrenceRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_occurrence), + '__call__') as call: + call.return_value = grafeas.Occurrence() + client.update_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_update_occurrence_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.UpdateOccurrenceRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_occurrence), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence()) + await client.update_occurrence(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_update_occurrence_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Occurrence() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_occurrence( + name='name_value', + occurrence=grafeas.Occurrence(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].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].occurrence + mock_val = grafeas.Occurrence(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_occurrence_flattened_error(): + client = GrafeasClient( + 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_occurrence( + grafeas.UpdateOccurrenceRequest(), + name='name_value', + occurrence=grafeas.Occurrence(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_occurrence_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Occurrence() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_occurrence( + name='name_value', + occurrence=grafeas.Occurrence(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].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].occurrence + mock_val = grafeas.Occurrence(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_occurrence_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_occurrence( + grafeas.UpdateOccurrenceRequest(), + name='name_value', + occurrence=grafeas.Occurrence(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + grafeas.GetOccurrenceNoteRequest, + dict, +]) +def test_get_occurrence_note(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_occurrence_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + ) + response = client.get_occurrence_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.GetOccurrenceNoteRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == 'name_value' + assert response.short_description == 'short_description_value' + assert response.long_description == 'long_description_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ['related_note_names_value'] + + +def test_get_occurrence_note_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.GetOccurrenceNoteRequest( + name='name_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence_note), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.get_occurrence_note(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.GetOccurrenceNoteRequest( + name='name_value', + ) + +def test_get_occurrence_note_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_occurrence_note in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.get_occurrence_note] = mock_rpc + request = {} + client.get_occurrence_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_occurrence_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_get_occurrence_note_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.get_occurrence_note in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.get_occurrence_note] = mock_rpc + + request = {} + await client.get_occurrence_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_occurrence_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_get_occurrence_note_async(transport: str = 'grpc_asyncio', request_type=grafeas.GetOccurrenceNoteRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_occurrence_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + )) + response = await client.get_occurrence_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.GetOccurrenceNoteRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == 'name_value' + assert response.short_description == 'short_description_value' + assert response.long_description == 'long_description_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ['related_note_names_value'] + + +@pytest.mark.asyncio +async def test_get_occurrence_note_async_from_dict(): + await test_get_occurrence_note_async(request_type=dict) + +def test_get_occurrence_note_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.GetOccurrenceNoteRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence_note), + '__call__') as call: + call.return_value = grafeas.Note() + client.get_occurrence_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_occurrence_note_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.GetOccurrenceNoteRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence_note), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) + await client.get_occurrence_note(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_occurrence_note_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Note() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_occurrence_note( + 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_occurrence_note_flattened_error(): + client = GrafeasClient( + 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_occurrence_note( + grafeas.GetOccurrenceNoteRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_occurrence_note_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Note() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_occurrence_note( + 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_occurrence_note_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_occurrence_note( + grafeas.GetOccurrenceNoteRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + grafeas.GetNoteRequest, + dict, +]) +def test_get_note(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + ) + response = client.get_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.GetNoteRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == 'name_value' + assert response.short_description == 'short_description_value' + assert response.long_description == 'long_description_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ['related_note_names_value'] + + +def test_get_note_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.GetNoteRequest( + name='name_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_note), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.get_note(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.GetNoteRequest( + name='name_value', + ) + +def test_get_note_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_note in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.get_note] = mock_rpc + request = {} + client.get_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_get_note_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.get_note in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.get_note] = mock_rpc + + request = {} + await client.get_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_get_note_async(transport: str = 'grpc_asyncio', request_type=grafeas.GetNoteRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + )) + response = await client.get_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.GetNoteRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == 'name_value' + assert response.short_description == 'short_description_value' + assert response.long_description == 'long_description_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ['related_note_names_value'] + + +@pytest.mark.asyncio +async def test_get_note_async_from_dict(): + await test_get_note_async(request_type=dict) + +def test_get_note_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.GetNoteRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_note), + '__call__') as call: + call.return_value = grafeas.Note() + client.get_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_note_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.GetNoteRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_note), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) + await client.get_note(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_note_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Note() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_note( + 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_note_flattened_error(): + client = GrafeasClient( + 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_note( + grafeas.GetNoteRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_note_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Note() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_note( + 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_note_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_note( + grafeas.GetNoteRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + grafeas.ListNotesRequest, + dict, +]) +def test_list_notes(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_notes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.ListNotesResponse( + next_page_token='next_page_token_value', + ) + response = client.list_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.ListNotesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListNotesPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_notes_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.ListNotesRequest( + parent='parent_value', + filter='filter_value', + page_token='page_token_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notes), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.list_notes(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.ListNotesRequest( + parent='parent_value', + filter='filter_value', + page_token='page_token_value', + ) + +def test_list_notes_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_notes in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.list_notes] = mock_rpc + request = {} + client.list_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_notes(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_notes_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.list_notes in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.list_notes] = mock_rpc + + request = {} + await client.list_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_notes(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_notes_async(transport: str = 'grpc_asyncio', request_type=grafeas.ListNotesRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_notes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNotesResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.ListNotesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListNotesAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_notes_async_from_dict(): + await test_list_notes_async(request_type=dict) + +def test_list_notes_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.ListNotesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notes), + '__call__') as call: + call.return_value = grafeas.ListNotesResponse() + client.list_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_notes_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.ListNotesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notes), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNotesResponse()) + await client.list_notes(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_notes_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.ListNotesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_notes( + parent='parent_value', + filter='filter_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].filter + mock_val = 'filter_value' + assert arg == mock_val + + +def test_list_notes_flattened_error(): + client = GrafeasClient( + 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_notes( + grafeas.ListNotesRequest(), + parent='parent_value', + filter='filter_value', + ) + +@pytest.mark.asyncio +async def test_list_notes_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.ListNotesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNotesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_notes( + parent='parent_value', + filter='filter_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].filter + mock_val = 'filter_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_notes_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_notes( + grafeas.ListNotesRequest(), + parent='parent_value', + filter='filter_value', + ) + + +def test_list_notes_pager(transport_name: str = "grpc"): + client = GrafeasClient( + 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_notes), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + grafeas.Note(), + grafeas.Note(), + ], + next_page_token='abc', + ), + grafeas.ListNotesResponse( + notes=[], + next_page_token='def', + ), + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + ], + next_page_token='ghi', + ), + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + grafeas.Note(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_notes(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, grafeas.Note) + for i in results) +def test_list_notes_pages(transport_name: str = "grpc"): + client = GrafeasClient( + 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_notes), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + grafeas.Note(), + grafeas.Note(), + ], + next_page_token='abc', + ), + grafeas.ListNotesResponse( + notes=[], + next_page_token='def', + ), + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + ], + next_page_token='ghi', + ), + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + grafeas.Note(), + ], + ), + RuntimeError, + ) + pages = list(client.list_notes(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_notes_async_pager(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notes), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + grafeas.Note(), + grafeas.Note(), + ], + next_page_token='abc', + ), + grafeas.ListNotesResponse( + notes=[], + next_page_token='def', + ), + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + ], + next_page_token='ghi', + ), + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + grafeas.Note(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_notes(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, grafeas.Note) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_notes_async_pages(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_notes), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + grafeas.Note(), + grafeas.Note(), + ], + next_page_token='abc', + ), + grafeas.ListNotesResponse( + notes=[], + next_page_token='def', + ), + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + ], + next_page_token='ghi', + ), + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + grafeas.Note(), + ], + ), + 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_notes(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", [ + grafeas.DeleteNoteRequest, + dict, +]) +def test_delete_note(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.DeleteNoteRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_note_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.DeleteNoteRequest( + name='name_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_note), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.delete_note(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.DeleteNoteRequest( + name='name_value', + ) + +def test_delete_note_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.delete_note in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.delete_note] = mock_rpc + request = {} + client.delete_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.delete_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_delete_note_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.delete_note in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.delete_note] = mock_rpc + + request = {} + await client.delete_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.delete_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_delete_note_async(transport: str = 'grpc_asyncio', request_type=grafeas.DeleteNoteRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.DeleteNoteRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_note_async_from_dict(): + await test_delete_note_async(request_type=dict) + +def test_delete_note_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.DeleteNoteRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_note), + '__call__') as call: + call.return_value = None + client.delete_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_note_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.DeleteNoteRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_note), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_note(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_note_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_note), + '__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_note( + 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_note_flattened_error(): + client = GrafeasClient( + 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_note( + grafeas.DeleteNoteRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_note_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_note), + '__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_note( + 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_note_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_note( + grafeas.DeleteNoteRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + grafeas.CreateNoteRequest, + dict, +]) +def test_create_note(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + ) + response = client.create_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.CreateNoteRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == 'name_value' + assert response.short_description == 'short_description_value' + assert response.long_description == 'long_description_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ['related_note_names_value'] + + +def test_create_note_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.CreateNoteRequest( + parent='parent_value', + note_id='note_id_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_note), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.create_note(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.CreateNoteRequest( + parent='parent_value', + note_id='note_id_value', + ) + +def test_create_note_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_note in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.create_note] = mock_rpc + request = {} + client.create_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_create_note_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.create_note in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.create_note] = mock_rpc + + request = {} + await client.create_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.create_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_create_note_async(transport: str = 'grpc_asyncio', request_type=grafeas.CreateNoteRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + )) + response = await client.create_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.CreateNoteRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == 'name_value' + assert response.short_description == 'short_description_value' + assert response.long_description == 'long_description_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ['related_note_names_value'] + + +@pytest.mark.asyncio +async def test_create_note_async_from_dict(): + await test_create_note_async(request_type=dict) + +def test_create_note_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.CreateNoteRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_note), + '__call__') as call: + call.return_value = grafeas.Note() + client.create_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_note_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.CreateNoteRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_note), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) + await client.create_note(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_note_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Note() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_note( + parent='parent_value', + note_id='note_id_value', + note=grafeas.Note(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].note_id + mock_val = 'note_id_value' + assert arg == mock_val + arg = args[0].note + mock_val = grafeas.Note(name='name_value') + assert arg == mock_val + + +def test_create_note_flattened_error(): + client = GrafeasClient( + 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_note( + grafeas.CreateNoteRequest(), + parent='parent_value', + note_id='note_id_value', + note=grafeas.Note(name='name_value'), + ) + +@pytest.mark.asyncio +async def test_create_note_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Note() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_note( + parent='parent_value', + note_id='note_id_value', + note=grafeas.Note(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].note_id + mock_val = 'note_id_value' + assert arg == mock_val + arg = args[0].note + mock_val = grafeas.Note(name='name_value') + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_note_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_note( + grafeas.CreateNoteRequest(), + parent='parent_value', + note_id='note_id_value', + note=grafeas.Note(name='name_value'), + ) + + +@pytest.mark.parametrize("request_type", [ + grafeas.BatchCreateNotesRequest, + dict, +]) +def test_batch_create_notes(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_create_notes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.BatchCreateNotesResponse( + ) + response = client.batch_create_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.BatchCreateNotesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.BatchCreateNotesResponse) + + +def test_batch_create_notes_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.BatchCreateNotesRequest( + parent='parent_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_notes), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.batch_create_notes(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.BatchCreateNotesRequest( + parent='parent_value', + ) + +def test_batch_create_notes_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.batch_create_notes in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.batch_create_notes] = mock_rpc + request = {} + client.batch_create_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_create_notes(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_batch_create_notes_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.batch_create_notes in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.batch_create_notes] = mock_rpc + + request = {} + await client.batch_create_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.batch_create_notes(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_batch_create_notes_async(transport: str = 'grpc_asyncio', request_type=grafeas.BatchCreateNotesRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_create_notes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateNotesResponse( + )) + response = await client.batch_create_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.BatchCreateNotesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.BatchCreateNotesResponse) + + +@pytest.mark.asyncio +async def test_batch_create_notes_async_from_dict(): + await test_batch_create_notes_async(request_type=dict) + +def test_batch_create_notes_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.BatchCreateNotesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_notes), + '__call__') as call: + call.return_value = grafeas.BatchCreateNotesResponse() + client.batch_create_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_batch_create_notes_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.BatchCreateNotesRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_notes), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateNotesResponse()) + await client.batch_create_notes(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_batch_create_notes_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_notes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.BatchCreateNotesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.batch_create_notes( + parent='parent_value', + notes={'key_value': grafeas.Note(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].notes + mock_val = {'key_value': grafeas.Note(name='name_value')} + assert arg == mock_val + + +def test_batch_create_notes_flattened_error(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_create_notes( + grafeas.BatchCreateNotesRequest(), + parent='parent_value', + notes={'key_value': grafeas.Note(name='name_value')}, + ) + +@pytest.mark.asyncio +async def test_batch_create_notes_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_notes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.BatchCreateNotesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateNotesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.batch_create_notes( + parent='parent_value', + notes={'key_value': grafeas.Note(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].notes + mock_val = {'key_value': grafeas.Note(name='name_value')} + assert arg == mock_val + +@pytest.mark.asyncio +async def test_batch_create_notes_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.batch_create_notes( + grafeas.BatchCreateNotesRequest(), + parent='parent_value', + notes={'key_value': grafeas.Note(name='name_value')}, + ) + + +@pytest.mark.parametrize("request_type", [ + grafeas.UpdateNoteRequest, + dict, +]) +def test_update_note(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + ) + response = client.update_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.UpdateNoteRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == 'name_value' + assert response.short_description == 'short_description_value' + assert response.long_description == 'long_description_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ['related_note_names_value'] + + +def test_update_note_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.UpdateNoteRequest( + name='name_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_note), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.update_note(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.UpdateNoteRequest( + name='name_value', + ) + +def test_update_note_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_note in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.update_note] = mock_rpc + request = {} + client.update_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_update_note_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.update_note in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.update_note] = mock_rpc + + request = {} + await client.update_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.update_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_update_note_async(transport: str = 'grpc_asyncio', request_type=grafeas.UpdateNoteRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + )) + response = await client.update_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.UpdateNoteRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == 'name_value' + assert response.short_description == 'short_description_value' + assert response.long_description == 'long_description_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ['related_note_names_value'] + + +@pytest.mark.asyncio +async def test_update_note_async_from_dict(): + await test_update_note_async(request_type=dict) + +def test_update_note_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.UpdateNoteRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_note), + '__call__') as call: + call.return_value = grafeas.Note() + client.update_note(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.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_update_note_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.UpdateNoteRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_note), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) + await client.update_note(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_update_note_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Note() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_note( + name='name_value', + note=grafeas.Note(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].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].note + mock_val = grafeas.Note(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_note_flattened_error(): + client = GrafeasClient( + 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_note( + grafeas.UpdateNoteRequest(), + name='name_value', + note=grafeas.Note(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_note_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.Note() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_note( + name='name_value', + note=grafeas.Note(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].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].note + mock_val = grafeas.Note(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_note_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_note( + grafeas.UpdateNoteRequest(), + name='name_value', + note=grafeas.Note(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + grafeas.ListNoteOccurrencesRequest, + dict, +]) +def test_list_note_occurrences(request_type, transport: str = 'grpc'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_note_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.ListNoteOccurrencesResponse( + next_page_token='next_page_token_value', + ) + response = client.list_note_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = grafeas.ListNoteOccurrencesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListNoteOccurrencesPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_note_occurrences_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = grafeas.ListNoteOccurrencesRequest( + name='name_value', + filter='filter_value', + page_token='page_token_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_note_occurrences), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.list_note_occurrences(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.ListNoteOccurrencesRequest( + name='name_value', + filter='filter_value', + page_token='page_token_value', + ) + +def test_list_note_occurrences_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_note_occurrences in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.list_note_occurrences] = mock_rpc + request = {} + client.list_note_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_note_occurrences(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_note_occurrences_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.list_note_occurrences in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.list_note_occurrences] = mock_rpc + + request = {} + await client.list_note_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_note_occurrences(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_note_occurrences_async(transport: str = 'grpc_asyncio', request_type=grafeas.ListNoteOccurrencesRequest): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an 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_note_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNoteOccurrencesResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_note_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = grafeas.ListNoteOccurrencesRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListNoteOccurrencesAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_note_occurrences_async_from_dict(): + await test_list_note_occurrences_async(request_type=dict) + +def test_list_note_occurrences_field_headers(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.ListNoteOccurrencesRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_note_occurrences), + '__call__') as call: + call.return_value = grafeas.ListNoteOccurrencesResponse() + client.list_note_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_list_note_occurrences_field_headers_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = grafeas.ListNoteOccurrencesRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_note_occurrences), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNoteOccurrencesResponse()) + await client.list_note_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + 'x-goog-request-params', + 'name=name_value', + ) in kw['metadata'] + + +def test_list_note_occurrences_flattened(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_note_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.ListNoteOccurrencesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_note_occurrences( + name='name_value', + filter='filter_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].filter + mock_val = 'filter_value' + assert arg == mock_val + + +def test_list_note_occurrences_flattened_error(): + client = GrafeasClient( + 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_note_occurrences( + grafeas.ListNoteOccurrencesRequest(), + name='name_value', + filter='filter_value', + ) + +@pytest.mark.asyncio +async def test_list_note_occurrences_flattened_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_note_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grafeas.ListNoteOccurrencesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNoteOccurrencesResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_note_occurrences( + name='name_value', + filter='filter_value', + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = 'name_value' + assert arg == mock_val + arg = args[0].filter + mock_val = 'filter_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_list_note_occurrences_flattened_error_async(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_note_occurrences( + grafeas.ListNoteOccurrencesRequest(), + name='name_value', + filter='filter_value', + ) + + +def test_list_note_occurrences_pager(transport_name: str = "grpc"): + client = GrafeasClient( + 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_note_occurrences), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + next_page_token='abc', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[], + next_page_token='def', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + ], + next_page_token='ghi', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('name', ''), + )), + ) + pager = client.list_note_occurrences(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, grafeas.Occurrence) + for i in results) +def test_list_note_occurrences_pages(transport_name: str = "grpc"): + client = GrafeasClient( + 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_note_occurrences), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + next_page_token='abc', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[], + next_page_token='def', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + ], + next_page_token='ghi', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + ), + RuntimeError, + ) + pages = list(client.list_note_occurrences(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_note_occurrences_async_pager(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_note_occurrences), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + next_page_token='abc', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[], + next_page_token='def', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + ], + next_page_token='ghi', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_note_occurrences(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, grafeas.Occurrence) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_note_occurrences_async_pages(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_note_occurrences), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + next_page_token='abc', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[], + next_page_token='def', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + ], + next_page_token='ghi', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + ), + 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_note_occurrences(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_get_occurrence_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_occurrence in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.get_occurrence] = mock_rpc + + request = {} + client.get_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_occurrence_rest_required_fields(request_type=grafeas.GetOccurrenceRequest): + transport_class = transports.GrafeasRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_occurrence._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_occurrence._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 = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.Occurrence() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_occurrence(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_occurrence_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_occurrence._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +def test_get_occurrence_rest_flattened(): + client = GrafeasClient( + 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 = grafeas.Occurrence() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/occurrences/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_occurrence(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/occurrences/*}" % client.transport._host, args[1]) + + +def test_get_occurrence_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + 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_occurrence( + grafeas.GetOccurrenceRequest(), + name='name_value', + ) + + +def test_list_occurrences_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_occurrences in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.list_occurrences] = mock_rpc + + request = {} + client.list_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_occurrences(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_occurrences_rest_required_fields(request_type=grafeas.ListOccurrencesRequest): + transport_class = transports.GrafeasRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_occurrences._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_occurrences._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 = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.ListOccurrencesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.ListOccurrencesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_occurrences(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_occurrences_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_occurrences._get_unset_required_fields({}) + assert set(unset_fields) == (set(("filter", "pageSize", "pageToken", )) & set(("parent", ))) + + +def test_list_occurrences_rest_flattened(): + client = GrafeasClient( + 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 = grafeas.ListOccurrencesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + filter='filter_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.ListOccurrencesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_occurrences(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*}/occurrences" % client.transport._host, args[1]) + + +def test_list_occurrences_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + 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_occurrences( + grafeas.ListOccurrencesRequest(), + parent='parent_value', + filter='filter_value', + ) + + +def test_list_occurrences_rest_pager(transport: str = 'rest'): + client = GrafeasClient( + 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 = ( + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + next_page_token='abc', + ), + grafeas.ListOccurrencesResponse( + occurrences=[], + next_page_token='def', + ), + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + ], + next_page_token='ghi', + ), + grafeas.ListOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(grafeas.ListOccurrencesResponse.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'} + + pager = client.list_occurrences(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, grafeas.Occurrence) + for i in results) + + pages = list(client.list_occurrences(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_delete_occurrence_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.delete_occurrence in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.delete_occurrence] = mock_rpc + + request = {} + client.delete_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.delete_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_occurrence_rest_required_fields(request_type=grafeas.DeleteOccurrenceRequest): + transport_class = transports.GrafeasRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_occurrence._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_occurrence._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 = GrafeasClient( + 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_occurrence(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_occurrence_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_occurrence._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +def test_delete_occurrence_rest_flattened(): + client = GrafeasClient( + 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/occurrences/sample2'} + + # 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_occurrence(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/occurrences/*}" % client.transport._host, args[1]) + + +def test_delete_occurrence_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + 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_occurrence( + grafeas.DeleteOccurrenceRequest(), + name='name_value', + ) + + +def test_create_occurrence_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_occurrence in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.create_occurrence] = mock_rpc + + request = {} + client.create_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_occurrence_rest_required_fields(request_type=grafeas.CreateOccurrenceRequest): + transport_class = transports.GrafeasRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_occurrence._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_occurrence._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 = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.Occurrence() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_occurrence(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_occurrence_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_occurrence._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "occurrence", ))) + + +def test_create_occurrence_rest_flattened(): + client = GrafeasClient( + 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 = grafeas.Occurrence() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + occurrence=grafeas.Occurrence(name='name_value'), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_occurrence(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*}/occurrences" % client.transport._host, args[1]) + + +def test_create_occurrence_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + 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_occurrence( + grafeas.CreateOccurrenceRequest(), + parent='parent_value', + occurrence=grafeas.Occurrence(name='name_value'), + ) + + +def test_batch_create_occurrences_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.batch_create_occurrences in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.batch_create_occurrences] = mock_rpc + + request = {} + client.batch_create_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_create_occurrences(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_create_occurrences_rest_required_fields(request_type=grafeas.BatchCreateOccurrencesRequest): + transport_class = transports.GrafeasRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_create_occurrences._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()).batch_create_occurrences._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 = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.BatchCreateOccurrencesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.BatchCreateOccurrencesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.batch_create_occurrences(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_batch_create_occurrences_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.batch_create_occurrences._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "occurrences", ))) + + +def test_batch_create_occurrences_rest_flattened(): + client = GrafeasClient( + 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 = grafeas.BatchCreateOccurrencesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + occurrences=[grafeas.Occurrence(name='name_value')], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.BatchCreateOccurrencesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.batch_create_occurrences(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*}/occurrences:batchCreate" % client.transport._host, args[1]) + + +def test_batch_create_occurrences_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_create_occurrences( + grafeas.BatchCreateOccurrencesRequest(), + parent='parent_value', + occurrences=[grafeas.Occurrence(name='name_value')], + ) + + +def test_update_occurrence_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_occurrence in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.update_occurrence] = mock_rpc + + request = {} + client.update_occurrence(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_occurrence(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_occurrence_rest_required_fields(request_type=grafeas.UpdateOccurrenceRequest): + transport_class = transports.GrafeasRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_occurrence._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()).update_occurrence._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 + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.Occurrence() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "patch", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_occurrence(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_occurrence_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_occurrence._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("name", "occurrence", ))) + + +def test_update_occurrence_rest_flattened(): + client = GrafeasClient( + 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 = grafeas.Occurrence() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/occurrences/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + occurrence=grafeas.Occurrence(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_occurrence(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/occurrences/*}" % client.transport._host, args[1]) + + +def test_update_occurrence_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + 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_occurrence( + grafeas.UpdateOccurrenceRequest(), + name='name_value', + occurrence=grafeas.Occurrence(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_get_occurrence_note_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_occurrence_note in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.get_occurrence_note] = mock_rpc + + request = {} + client.get_occurrence_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_occurrence_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_occurrence_note_rest_required_fields(request_type=grafeas.GetOccurrenceNoteRequest): + transport_class = transports.GrafeasRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_occurrence_note._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_occurrence_note._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 = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.Note() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_occurrence_note(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_occurrence_note_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_occurrence_note._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +def test_get_occurrence_note_rest_flattened(): + client = GrafeasClient( + 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 = grafeas.Note() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/occurrences/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_occurrence_note(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/occurrences/*}/notes" % client.transport._host, args[1]) + + +def test_get_occurrence_note_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + 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_occurrence_note( + grafeas.GetOccurrenceNoteRequest(), + name='name_value', + ) + + +def test_get_note_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_note in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.get_note] = mock_rpc + + request = {} + client.get_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_note_rest_required_fields(request_type=grafeas.GetNoteRequest): + transport_class = transports.GrafeasRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_note._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_note._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 = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.Note() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_note(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_note_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_note._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +def test_get_note_rest_flattened(): + client = GrafeasClient( + 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 = grafeas.Note() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/notes/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_note(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/notes/*}" % client.transport._host, args[1]) + + +def test_get_note_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + 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_note( + grafeas.GetNoteRequest(), + name='name_value', + ) + + +def test_list_notes_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_notes in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.list_notes] = mock_rpc + + request = {} + client.list_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_notes(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_notes_rest_required_fields(request_type=grafeas.ListNotesRequest): + transport_class = transports.GrafeasRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_notes._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_notes._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 = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.ListNotesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.ListNotesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_notes(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_notes_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_notes._get_unset_required_fields({}) + assert set(unset_fields) == (set(("filter", "pageSize", "pageToken", )) & set(("parent", ))) + + +def test_list_notes_rest_flattened(): + client = GrafeasClient( + 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 = grafeas.ListNotesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + filter='filter_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.ListNotesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_notes(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*}/notes" % client.transport._host, args[1]) + + +def test_list_notes_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + 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_notes( + grafeas.ListNotesRequest(), + parent='parent_value', + filter='filter_value', + ) + + +def test_list_notes_rest_pager(transport: str = 'rest'): + client = GrafeasClient( + 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 = ( + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + grafeas.Note(), + grafeas.Note(), + ], + next_page_token='abc', + ), + grafeas.ListNotesResponse( + notes=[], + next_page_token='def', + ), + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + ], + next_page_token='ghi', + ), + grafeas.ListNotesResponse( + notes=[ + grafeas.Note(), + grafeas.Note(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(grafeas.ListNotesResponse.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'} + + pager = client.list_notes(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, grafeas.Note) + for i in results) + + pages = list(client.list_notes(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_delete_note_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.delete_note in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.delete_note] = mock_rpc + + request = {} + client.delete_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.delete_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_note_rest_required_fields(request_type=grafeas.DeleteNoteRequest): + transport_class = transports.GrafeasRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_note._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_note._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 = GrafeasClient( + 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_note(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_note_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_note._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +def test_delete_note_rest_flattened(): + client = GrafeasClient( + 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/notes/sample2'} + + # 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_note(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/notes/*}" % client.transport._host, args[1]) + + +def test_delete_note_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + 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_note( + grafeas.DeleteNoteRequest(), + name='name_value', + ) + + +def test_create_note_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_note in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.create_note] = mock_rpc + + request = {} + client.create_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_note_rest_required_fields(request_type=grafeas.CreateNoteRequest): + transport_class = transports.GrafeasRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["note_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads(json_format.MessageToJson( + pb_request, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + assert "noteId" not in jsonified_request + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_note._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "noteId" in jsonified_request + assert jsonified_request["noteId"] == request_init["note_id"] + + jsonified_request["parent"] = 'parent_value' + jsonified_request["noteId"] = 'note_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_note._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("note_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 "noteId" in jsonified_request + assert jsonified_request["noteId"] == 'note_id_value' + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.Note() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_note(request) + + expected_params = [ + ( + "noteId", + "", + ), + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_note_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_note._get_unset_required_fields({}) + assert set(unset_fields) == (set(("noteId", )) & set(("parent", "noteId", "note", ))) + + +def test_create_note_rest_flattened(): + client = GrafeasClient( + 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 = grafeas.Note() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + note_id='note_id_value', + note=grafeas.Note(name='name_value'), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_note(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*}/notes" % client.transport._host, args[1]) + + +def test_create_note_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + 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_note( + grafeas.CreateNoteRequest(), + parent='parent_value', + note_id='note_id_value', + note=grafeas.Note(name='name_value'), + ) + + +def test_batch_create_notes_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.batch_create_notes in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.batch_create_notes] = mock_rpc + + request = {} + client.batch_create_notes(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_create_notes(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_create_notes_rest_required_fields(request_type=grafeas.BatchCreateNotesRequest): + transport_class = transports.GrafeasRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_create_notes._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()).batch_create_notes._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 = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.BatchCreateNotesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "post", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.BatchCreateNotesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.batch_create_notes(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_batch_create_notes_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.batch_create_notes._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "notes", ))) + + +def test_batch_create_notes_rest_flattened(): + client = GrafeasClient( + 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 = grafeas.BatchCreateNotesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + notes={'key_value': grafeas.Note(name='name_value')}, + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.BatchCreateNotesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.batch_create_notes(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{parent=projects/*}/notes:batchCreate" % client.transport._host, args[1]) + + +def test_batch_create_notes_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_create_notes( + grafeas.BatchCreateNotesRequest(), + parent='parent_value', + notes={'key_value': grafeas.Note(name='name_value')}, + ) + + +def test_update_note_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_note in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.update_note] = mock_rpc + + request = {} + client.update_note(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_note(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_note_rest_required_fields(request_type=grafeas.UpdateNoteRequest): + transport_class = transports.GrafeasRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_note._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()).update_note._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 + assert "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.Note() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "patch", + 'query_params': pb_request, + } + transcode_result['body'] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_note(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_note_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_note._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("name", "note", ))) + + +def test_update_note_rest_flattened(): + client = GrafeasClient( + 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 = grafeas.Note() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/notes/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + note=grafeas.Note(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_note(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/notes/*}" % client.transport._host, args[1]) + + +def test_update_note_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + 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_note( + grafeas.UpdateNoteRequest(), + name='name_value', + note=grafeas.Note(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_list_note_occurrences_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_note_occurrences in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.list_note_occurrences] = mock_rpc + + request = {} + client.list_note_occurrences(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_note_occurrences(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_note_occurrences_rest_required_fields(request_type=grafeas.ListNoteOccurrencesRequest): + transport_class = transports.GrafeasRestTransport + + 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, + use_integers_for_enums=False + )) + + # verify fields with default values are dropped + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_note_occurrences._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = 'name_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_note_occurrences._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 "name" in jsonified_request + assert jsonified_request["name"] == 'name_value' + + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = grafeas.ListNoteOccurrencesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, 'request') as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, 'transcode') as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + 'uri': 'v1/sample_method', + 'method': "get", + 'query_params': pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.ListNoteOccurrencesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_note_occurrences(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_note_occurrences_rest_unset_required_fields(): + transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_note_occurrences._get_unset_required_fields({}) + assert set(unset_fields) == (set(("filter", "pageSize", "pageToken", )) & set(("name", ))) + + +def test_list_note_occurrences_rest_flattened(): + client = GrafeasClient( + 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 = grafeas.ListNoteOccurrencesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/notes/sample2'} + + # get truthy value for each flattened field + mock_args = dict( + name='name_value', + filter='filter_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = grafeas.ListNoteOccurrencesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_note_occurrences(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate("%s/v1/{name=projects/*/notes/*}/occurrences" % client.transport._host, args[1]) + + +def test_list_note_occurrences_rest_flattened_error(transport: str = 'rest'): + client = GrafeasClient( + 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_note_occurrences( + grafeas.ListNoteOccurrencesRequest(), + name='name_value', + filter='filter_value', + ) + + +def test_list_note_occurrences_rest_pager(transport: str = 'rest'): + client = GrafeasClient( + 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 = ( + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + next_page_token='abc', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[], + next_page_token='def', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + ], + next_page_token='ghi', + ), + grafeas.ListNoteOccurrencesResponse( + occurrences=[ + grafeas.Occurrence(), + grafeas.Occurrence(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(grafeas.ListNoteOccurrencesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode('UTF-8') + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {'name': 'projects/sample1/notes/sample2'} + + pager = client.list_note_occurrences(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, grafeas.Occurrence) + for i in results) + + pages = list(client.list_note_occurrences(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.GrafeasGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.GrafeasGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = GrafeasClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.GrafeasGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = GrafeasClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = GrafeasClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.GrafeasGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = GrafeasClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.GrafeasGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = GrafeasClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.GrafeasGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.GrafeasGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.GrafeasGrpcTransport, + transports.GrafeasGrpcAsyncIOTransport, + transports.GrafeasRestTransport, +]) +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() + +def test_transport_kind_grpc(): + transport = GrafeasClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_occurrence_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence), + '__call__') as call: + call.return_value = grafeas.Occurrence() + client.get_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_occurrences_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_occurrences), + '__call__') as call: + call.return_value = grafeas.ListOccurrencesResponse() + client.list_occurrences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListOccurrencesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_occurrence_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_occurrence), + '__call__') as call: + call.return_value = None + client.delete_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.DeleteOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_occurrence_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_occurrence), + '__call__') as call: + call.return_value = grafeas.Occurrence() + client.create_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.CreateOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_occurrences_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_occurrences), + '__call__') as call: + call.return_value = grafeas.BatchCreateOccurrencesResponse() + client.batch_create_occurrences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.BatchCreateOccurrencesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_occurrence_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_occurrence), + '__call__') as call: + call.return_value = grafeas.Occurrence() + client.update_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.UpdateOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_occurrence_note_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence_note), + '__call__') as call: + call.return_value = grafeas.Note() + client.get_occurrence_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetOccurrenceNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_note_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_note), + '__call__') as call: + call.return_value = grafeas.Note() + client.get_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_notes_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_notes), + '__call__') as call: + call.return_value = grafeas.ListNotesResponse() + client.list_notes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListNotesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_note_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_note), + '__call__') as call: + call.return_value = None + client.delete_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.DeleteNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_note_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_note), + '__call__') as call: + call.return_value = grafeas.Note() + client.create_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.CreateNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_notes_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_notes), + '__call__') as call: + call.return_value = grafeas.BatchCreateNotesResponse() + client.batch_create_notes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.BatchCreateNotesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_note_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_note), + '__call__') as call: + call.return_value = grafeas.Note() + client.update_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.UpdateNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_note_occurrences_empty_call_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_note_occurrences), + '__call__') as call: + call.return_value = grafeas.ListNoteOccurrencesResponse() + client.list_note_occurrences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListNoteOccurrencesRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = GrafeasAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_occurrence_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence( + name='name_value', + resource_uri='resource_uri_value', + note_name='note_name_value', + kind=common.NoteKind.VULNERABILITY, + remediation='remediation_value', + )) + await client.get_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_occurrences_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListOccurrencesResponse( + next_page_token='next_page_token_value', + )) + await client.list_occurrences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListOccurrencesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_occurrence_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.DeleteOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_occurrence_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence( + name='name_value', + resource_uri='resource_uri_value', + note_name='note_name_value', + kind=common.NoteKind.VULNERABILITY, + remediation='remediation_value', + )) + await client.create_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.CreateOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_batch_create_occurrences_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateOccurrencesResponse( + )) + await client.batch_create_occurrences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.BatchCreateOccurrencesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_occurrence_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_occurrence), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence( + name='name_value', + resource_uri='resource_uri_value', + note_name='note_name_value', + kind=common.NoteKind.VULNERABILITY, + remediation='remediation_value', + )) + await client.update_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.UpdateOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_occurrence_note_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + )) + await client.get_occurrence_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetOccurrenceNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_note_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + )) + await client.get_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_notes_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_notes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNotesResponse( + next_page_token='next_page_token_value', + )) + await client.list_notes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListNotesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_note_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.DeleteNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_note_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + )) + await client.create_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.CreateNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_batch_create_notes_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_notes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateNotesResponse( + )) + await client.batch_create_notes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.BatchCreateNotesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_note_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_note), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + )) + await client.update_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.UpdateNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_note_occurrences_empty_call_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_note_occurrences), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNoteOccurrencesResponse( + next_page_token='next_page_token_value', + )) + await client.list_note_occurrences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListNoteOccurrencesRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = GrafeasClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_occurrence_rest_bad_request(request_type=grafeas.GetOccurrenceRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/occurrences/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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_occurrence(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.GetOccurrenceRequest, + dict, +]) +def test_get_occurrence_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/occurrences/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 = grafeas.Occurrence( + name='name_value', + resource_uri='resource_uri_value', + note_name='note_name_value', + kind=common.NoteKind.VULNERABILITY, + remediation='remediation_value', + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_occurrence(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Occurrence) + assert response.name == 'name_value' + assert response.resource_uri == 'resource_uri_value' + assert response.note_name == 'note_name_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.remediation == 'remediation_value' + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_occurrence_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "post_get_occurrence") as post, \ + mock.patch.object(transports.GrafeasRestInterceptor, "pre_get_occurrence") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.GetOccurrenceRequest.pb(grafeas.GetOccurrenceRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.Occurrence.to_json(grafeas.Occurrence()) + req.return_value.content = return_value + + request = grafeas.GetOccurrenceRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.Occurrence() + + client.get_occurrence(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_occurrences_rest_bad_request(request_type=grafeas.ListOccurrencesRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1'} + 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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_occurrences(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.ListOccurrencesRequest, + dict, +]) +def test_list_occurrences_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.ListOccurrencesResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.ListOccurrencesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_occurrences(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListOccurrencesPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_occurrences_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "post_list_occurrences") as post, \ + mock.patch.object(transports.GrafeasRestInterceptor, "pre_list_occurrences") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.ListOccurrencesRequest.pb(grafeas.ListOccurrencesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.ListOccurrencesResponse.to_json(grafeas.ListOccurrencesResponse()) + req.return_value.content = return_value + + request = grafeas.ListOccurrencesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.ListOccurrencesResponse() + + client.list_occurrences(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_delete_occurrence_rest_bad_request(request_type=grafeas.DeleteOccurrenceRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/occurrences/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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.delete_occurrence(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.DeleteOccurrenceRequest, + dict, +]) +def test_delete_occurrence_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/occurrences/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 = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + 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_occurrence(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_occurrence_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "pre_delete_occurrence") as pre: + pre.assert_not_called() + pb_message = grafeas.DeleteOccurrenceRequest.pb(grafeas.DeleteOccurrenceRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = grafeas.DeleteOccurrenceRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_occurrence(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_create_occurrence_rest_bad_request(request_type=grafeas.CreateOccurrenceRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1'} + 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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_occurrence(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.CreateOccurrenceRequest, + dict, +]) +def test_create_occurrence_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1'} + request_init["occurrence"] = {'name': 'name_value', 'resource_uri': 'resource_uri_value', 'note_name': 'note_name_value', 'kind': 1, 'remediation': 'remediation_value', 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'vulnerability': {'type_': 'type__value', 'severity': 1, 'cvss_score': 0.1082, 'cvssv3': {'base_score': 0.1046, 'exploitability_score': 0.21580000000000002, 'impact_score': 0.1273, 'attack_vector': 1, 'attack_complexity': 1, 'authentication': 1, 'privileges_required': 1, 'user_interaction': 1, 'scope': 1, 'confidentiality_impact': 1, 'integrity_impact': 1, 'availability_impact': 1}, 'package_issue': [{'affected_cpe_uri': 'affected_cpe_uri_value', 'affected_package': 'affected_package_value', 'affected_version': {'epoch': 527, 'name': 'name_value', 'revision': 'revision_value', 'inclusive': True, 'kind': 1, 'full_name': 'full_name_value'}, 'fixed_cpe_uri': 'fixed_cpe_uri_value', 'fixed_package': 'fixed_package_value', 'fixed_version': {}, 'fix_available': True, 'package_type': 'package_type_value', 'effective_severity': 1, 'file_location': [{'file_path': 'file_path_value'}]}], 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'related_urls': [{'url': 'url_value', 'label': 'label_value'}], 'effective_severity': 1, 'fix_available': True, 'cvss_version': 1, 'cvss_v2': {}, 'vex_assessment': {'cve': 'cve_value', 'vulnerability_id': 'vulnerability_id_value', 'related_uris': {}, 'note_name': 'note_name_value', 'state': 1, 'impacts': ['impacts_value1', 'impacts_value2'], 'remediations': [{'remediation_type': 1, 'details': 'details_value', 'remediation_uri': {}}], 'justification': {'justification_type': 1, 'details': 'details_value'}}, 'extra_details': 'extra_details_value'}, 'build': {'provenance': {'id': 'id_value', 'project_id': 'project_id_value', 'commands': [{'name': 'name_value', 'env': ['env_value1', 'env_value2'], 'args': ['args_value1', 'args_value2'], 'dir_': 'dir__value', 'id': 'id_value', 'wait_for': ['wait_for_value1', 'wait_for_value2']}], 'built_artifacts': [{'checksum': 'checksum_value', 'id': 'id_value', 'names': ['names_value1', 'names_value2']}], 'create_time': {}, 'start_time': {}, 'end_time': {}, 'creator': 'creator_value', 'logs_uri': 'logs_uri_value', 'source_provenance': {'artifact_storage_source_uri': 'artifact_storage_source_uri_value', 'file_hashes': {}, 'context': {'cloud_repo': {'repo_id': {'project_repo_id': {'project_id': 'project_id_value', 'repo_name': 'repo_name_value'}, 'uid': 'uid_value'}, 'revision_id': 'revision_id_value', 'alias_context': {'kind': 1, 'name': 'name_value'}}, 'gerrit': {'host_uri': 'host_uri_value', 'gerrit_project': 'gerrit_project_value', 'revision_id': 'revision_id_value', 'alias_context': {}}, 'git': {'url': 'url_value', 'revision_id': 'revision_id_value'}, 'labels': {}}, 'additional_contexts': {}}, 'trigger_id': 'trigger_id_value', 'build_options': {}, 'builder_version': 'builder_version_value'}, 'provenance_bytes': 'provenance_bytes_value', 'intoto_provenance': {'builder_config': {'id': 'id_value'}, 'recipe': {'type_': 'type__value', 'defined_in_material': 1971, 'entry_point': 'entry_point_value', 'arguments': [{'type_url': 'type.googleapis.com/google.protobuf.Duration', 'value': b'\x08\x0c\x10\xdb\x07'}], 'environment': {}}, 'metadata': {'build_invocation_id': 'build_invocation_id_value', 'build_started_on': {}, 'build_finished_on': {}, 'completeness': {'arguments': True, 'environment': True, 'materials': True}, 'reproducible': True}, 'materials': ['materials_value1', 'materials_value2']}, 'intoto_statement': {'type_': 'type__value', 'subject': [{'name': 'name_value', 'digest': {}}], 'predicate_type': 'predicate_type_value', 'provenance': {}, 'slsa_provenance': {'builder': {'id': 'id_value'}, 'recipe': {'type_': 'type__value', 'defined_in_material': 1971, 'entry_point': 'entry_point_value', 'arguments': {}, 'environment': {}}, 'metadata': {'build_invocation_id': 'build_invocation_id_value', 'build_started_on': {}, 'build_finished_on': {}, 'completeness': {'arguments': True, 'environment': True, 'materials': True}, 'reproducible': True}, 'materials': [{'uri': 'uri_value', 'digest': {}}]}, 'slsa_provenance_zero_two': {'builder': {'id': 'id_value'}, 'build_type': 'build_type_value', 'invocation': {'config_source': {'uri': 'uri_value', 'digest': {}, 'entry_point': 'entry_point_value'}, 'parameters': {'fields': {}}, 'environment': {}}, 'build_config': {}, 'metadata': {'build_invocation_id': 'build_invocation_id_value', 'build_started_on': {}, 'build_finished_on': {}, 'completeness': {'parameters': True, 'environment': True, 'materials': True}, 'reproducible': True}, 'materials': [{'uri': 'uri_value', 'digest': {}}]}}, 'in_toto_slsa_provenance_v1': {'type_': 'type__value', 'subject': {}, 'predicate_type': 'predicate_type_value', 'predicate': {'build_definition': {'build_type': 'build_type_value', 'external_parameters': {}, 'internal_parameters': {}, 'resolved_dependencies': [{'name': 'name_value', 'uri': 'uri_value', 'digest': {}, 'content': b'content_blob', 'download_location': 'download_location_value', 'media_type': 'media_type_value', 'annotations': {}}]}, 'run_details': {'builder': {'id': 'id_value', 'version': {}, 'builder_dependencies': {}}, 'metadata': {'invocation_id': 'invocation_id_value', 'started_on': {}, 'finished_on': {}}, 'byproducts': {}}}}}, 'image': {'fingerprint': {'v1_name': 'v1_name_value', 'v2_blob': ['v2_blob_value1', 'v2_blob_value2'], 'v2_name': 'v2_name_value'}, 'distance': 843, 'layer_info': [{'directive': 'directive_value', 'arguments': 'arguments_value'}], 'base_resource_url': 'base_resource_url_value'}, 'package': {'name': 'name_value', 'location': [{'cpe_uri': 'cpe_uri_value', 'version': {}, 'path': 'path_value'}], 'package_type': 'package_type_value', 'cpe_uri': 'cpe_uri_value', 'architecture': 1, 'license_': {'expression': 'expression_value', 'comments': 'comments_value'}, 'version': {}}, 'deployment': {'user_email': 'user_email_value', 'deploy_time': {}, 'undeploy_time': {}, 'config': 'config_value', 'address': 'address_value', 'resource_uri': ['resource_uri_value1', 'resource_uri_value2'], 'platform': 1}, 'discovery': {'continuous_analysis': 1, 'analysis_status': 1, 'analysis_completed': {'analysis_type': ['analysis_type_value1', 'analysis_type_value2']}, 'analysis_error': [{'code': 411, 'message': 'message_value', 'details': {}}], 'analysis_status_error': {}, 'cpe': 'cpe_value', 'last_scan_time': {}, 'archive_time': {}, 'sbom_status': {'sbom_state': 1, 'error': 'error_value'}, 'vulnerability_attestation': {'last_attempt_time': {}, 'state': 1, 'error': 'error_value'}}, 'attestation': {'serialized_payload': b'serialized_payload_blob', 'signatures': [{'signature': b'signature_blob', 'public_key_id': 'public_key_id_value'}], 'jwts': [{'compact_jwt': 'compact_jwt_value'}]}, 'upgrade': {'package': 'package_value', 'parsed_version': {}, 'distribution': {'cpe_uri': 'cpe_uri_value', 'classification': 'classification_value', 'severity': 'severity_value', 'cve': ['cve_value1', 'cve_value2']}, 'windows_update': {'identity': {'update_id': 'update_id_value', 'revision': 879}, 'title': 'title_value', 'description': 'description_value', 'categories': [{'category_id': 'category_id_value', 'name': 'name_value'}], 'kb_article_ids': ['kb_article_ids_value1', 'kb_article_ids_value2'], 'support_url': 'support_url_value', 'last_published_timestamp': {}}}, 'compliance': {'non_compliant_files': [{'path': 'path_value', 'display_command': 'display_command_value', 'reason': 'reason_value'}], 'non_compliance_reason': 'non_compliance_reason_value', 'version': {'cpe_uri': 'cpe_uri_value', 'benchmark_document': 'benchmark_document_value', 'version': 'version_value'}}, 'dsse_attestation': {'envelope': {'payload': b'payload_blob', 'payload_type': 'payload_type_value', 'signatures': [{'sig': b'sig_blob', 'keyid': 'keyid_value'}]}, 'statement': {}}, 'sbom_reference': {'payload': {'type_': 'type__value', 'predicate_type': 'predicate_type_value', 'subject': {}, 'predicate': {'referrer_id': 'referrer_id_value', 'location': 'location_value', 'mime_type': 'mime_type_value', 'digest': {}}}, 'payload_type': 'payload_type_value', 'signatures': {}}, 'envelope': {}} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = grafeas.CreateOccurrenceRequest.meta.fields["occurrence"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["occurrence"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["occurrence"][field])): + del request_init["occurrence"][field][i][subfield] + else: + del request_init["occurrence"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Occurrence( + name='name_value', + resource_uri='resource_uri_value', + note_name='note_name_value', + kind=common.NoteKind.VULNERABILITY, + remediation='remediation_value', + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_occurrence(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Occurrence) + assert response.name == 'name_value' + assert response.resource_uri == 'resource_uri_value' + assert response.note_name == 'note_name_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.remediation == 'remediation_value' + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_occurrence_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "post_create_occurrence") as post, \ + mock.patch.object(transports.GrafeasRestInterceptor, "pre_create_occurrence") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.CreateOccurrenceRequest.pb(grafeas.CreateOccurrenceRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.Occurrence.to_json(grafeas.Occurrence()) + req.return_value.content = return_value + + request = grafeas.CreateOccurrenceRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.Occurrence() + + client.create_occurrence(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_batch_create_occurrences_rest_bad_request(request_type=grafeas.BatchCreateOccurrencesRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1'} + 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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.batch_create_occurrences(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.BatchCreateOccurrencesRequest, + dict, +]) +def test_batch_create_occurrences_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.BatchCreateOccurrencesResponse( + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.BatchCreateOccurrencesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.batch_create_occurrences(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.BatchCreateOccurrencesResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_create_occurrences_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "post_batch_create_occurrences") as post, \ + mock.patch.object(transports.GrafeasRestInterceptor, "pre_batch_create_occurrences") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.BatchCreateOccurrencesRequest.pb(grafeas.BatchCreateOccurrencesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.BatchCreateOccurrencesResponse.to_json(grafeas.BatchCreateOccurrencesResponse()) + req.return_value.content = return_value + + request = grafeas.BatchCreateOccurrencesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.BatchCreateOccurrencesResponse() + + client.batch_create_occurrences(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_occurrence_rest_bad_request(request_type=grafeas.UpdateOccurrenceRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/occurrences/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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_occurrence(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.UpdateOccurrenceRequest, + dict, +]) +def test_update_occurrence_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/occurrences/sample2'} + request_init["occurrence"] = {'name': 'name_value', 'resource_uri': 'resource_uri_value', 'note_name': 'note_name_value', 'kind': 1, 'remediation': 'remediation_value', 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'vulnerability': {'type_': 'type__value', 'severity': 1, 'cvss_score': 0.1082, 'cvssv3': {'base_score': 0.1046, 'exploitability_score': 0.21580000000000002, 'impact_score': 0.1273, 'attack_vector': 1, 'attack_complexity': 1, 'authentication': 1, 'privileges_required': 1, 'user_interaction': 1, 'scope': 1, 'confidentiality_impact': 1, 'integrity_impact': 1, 'availability_impact': 1}, 'package_issue': [{'affected_cpe_uri': 'affected_cpe_uri_value', 'affected_package': 'affected_package_value', 'affected_version': {'epoch': 527, 'name': 'name_value', 'revision': 'revision_value', 'inclusive': True, 'kind': 1, 'full_name': 'full_name_value'}, 'fixed_cpe_uri': 'fixed_cpe_uri_value', 'fixed_package': 'fixed_package_value', 'fixed_version': {}, 'fix_available': True, 'package_type': 'package_type_value', 'effective_severity': 1, 'file_location': [{'file_path': 'file_path_value'}]}], 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'related_urls': [{'url': 'url_value', 'label': 'label_value'}], 'effective_severity': 1, 'fix_available': True, 'cvss_version': 1, 'cvss_v2': {}, 'vex_assessment': {'cve': 'cve_value', 'vulnerability_id': 'vulnerability_id_value', 'related_uris': {}, 'note_name': 'note_name_value', 'state': 1, 'impacts': ['impacts_value1', 'impacts_value2'], 'remediations': [{'remediation_type': 1, 'details': 'details_value', 'remediation_uri': {}}], 'justification': {'justification_type': 1, 'details': 'details_value'}}, 'extra_details': 'extra_details_value'}, 'build': {'provenance': {'id': 'id_value', 'project_id': 'project_id_value', 'commands': [{'name': 'name_value', 'env': ['env_value1', 'env_value2'], 'args': ['args_value1', 'args_value2'], 'dir_': 'dir__value', 'id': 'id_value', 'wait_for': ['wait_for_value1', 'wait_for_value2']}], 'built_artifacts': [{'checksum': 'checksum_value', 'id': 'id_value', 'names': ['names_value1', 'names_value2']}], 'create_time': {}, 'start_time': {}, 'end_time': {}, 'creator': 'creator_value', 'logs_uri': 'logs_uri_value', 'source_provenance': {'artifact_storage_source_uri': 'artifact_storage_source_uri_value', 'file_hashes': {}, 'context': {'cloud_repo': {'repo_id': {'project_repo_id': {'project_id': 'project_id_value', 'repo_name': 'repo_name_value'}, 'uid': 'uid_value'}, 'revision_id': 'revision_id_value', 'alias_context': {'kind': 1, 'name': 'name_value'}}, 'gerrit': {'host_uri': 'host_uri_value', 'gerrit_project': 'gerrit_project_value', 'revision_id': 'revision_id_value', 'alias_context': {}}, 'git': {'url': 'url_value', 'revision_id': 'revision_id_value'}, 'labels': {}}, 'additional_contexts': {}}, 'trigger_id': 'trigger_id_value', 'build_options': {}, 'builder_version': 'builder_version_value'}, 'provenance_bytes': 'provenance_bytes_value', 'intoto_provenance': {'builder_config': {'id': 'id_value'}, 'recipe': {'type_': 'type__value', 'defined_in_material': 1971, 'entry_point': 'entry_point_value', 'arguments': [{'type_url': 'type.googleapis.com/google.protobuf.Duration', 'value': b'\x08\x0c\x10\xdb\x07'}], 'environment': {}}, 'metadata': {'build_invocation_id': 'build_invocation_id_value', 'build_started_on': {}, 'build_finished_on': {}, 'completeness': {'arguments': True, 'environment': True, 'materials': True}, 'reproducible': True}, 'materials': ['materials_value1', 'materials_value2']}, 'intoto_statement': {'type_': 'type__value', 'subject': [{'name': 'name_value', 'digest': {}}], 'predicate_type': 'predicate_type_value', 'provenance': {}, 'slsa_provenance': {'builder': {'id': 'id_value'}, 'recipe': {'type_': 'type__value', 'defined_in_material': 1971, 'entry_point': 'entry_point_value', 'arguments': {}, 'environment': {}}, 'metadata': {'build_invocation_id': 'build_invocation_id_value', 'build_started_on': {}, 'build_finished_on': {}, 'completeness': {'arguments': True, 'environment': True, 'materials': True}, 'reproducible': True}, 'materials': [{'uri': 'uri_value', 'digest': {}}]}, 'slsa_provenance_zero_two': {'builder': {'id': 'id_value'}, 'build_type': 'build_type_value', 'invocation': {'config_source': {'uri': 'uri_value', 'digest': {}, 'entry_point': 'entry_point_value'}, 'parameters': {'fields': {}}, 'environment': {}}, 'build_config': {}, 'metadata': {'build_invocation_id': 'build_invocation_id_value', 'build_started_on': {}, 'build_finished_on': {}, 'completeness': {'parameters': True, 'environment': True, 'materials': True}, 'reproducible': True}, 'materials': [{'uri': 'uri_value', 'digest': {}}]}}, 'in_toto_slsa_provenance_v1': {'type_': 'type__value', 'subject': {}, 'predicate_type': 'predicate_type_value', 'predicate': {'build_definition': {'build_type': 'build_type_value', 'external_parameters': {}, 'internal_parameters': {}, 'resolved_dependencies': [{'name': 'name_value', 'uri': 'uri_value', 'digest': {}, 'content': b'content_blob', 'download_location': 'download_location_value', 'media_type': 'media_type_value', 'annotations': {}}]}, 'run_details': {'builder': {'id': 'id_value', 'version': {}, 'builder_dependencies': {}}, 'metadata': {'invocation_id': 'invocation_id_value', 'started_on': {}, 'finished_on': {}}, 'byproducts': {}}}}}, 'image': {'fingerprint': {'v1_name': 'v1_name_value', 'v2_blob': ['v2_blob_value1', 'v2_blob_value2'], 'v2_name': 'v2_name_value'}, 'distance': 843, 'layer_info': [{'directive': 'directive_value', 'arguments': 'arguments_value'}], 'base_resource_url': 'base_resource_url_value'}, 'package': {'name': 'name_value', 'location': [{'cpe_uri': 'cpe_uri_value', 'version': {}, 'path': 'path_value'}], 'package_type': 'package_type_value', 'cpe_uri': 'cpe_uri_value', 'architecture': 1, 'license_': {'expression': 'expression_value', 'comments': 'comments_value'}, 'version': {}}, 'deployment': {'user_email': 'user_email_value', 'deploy_time': {}, 'undeploy_time': {}, 'config': 'config_value', 'address': 'address_value', 'resource_uri': ['resource_uri_value1', 'resource_uri_value2'], 'platform': 1}, 'discovery': {'continuous_analysis': 1, 'analysis_status': 1, 'analysis_completed': {'analysis_type': ['analysis_type_value1', 'analysis_type_value2']}, 'analysis_error': [{'code': 411, 'message': 'message_value', 'details': {}}], 'analysis_status_error': {}, 'cpe': 'cpe_value', 'last_scan_time': {}, 'archive_time': {}, 'sbom_status': {'sbom_state': 1, 'error': 'error_value'}, 'vulnerability_attestation': {'last_attempt_time': {}, 'state': 1, 'error': 'error_value'}}, 'attestation': {'serialized_payload': b'serialized_payload_blob', 'signatures': [{'signature': b'signature_blob', 'public_key_id': 'public_key_id_value'}], 'jwts': [{'compact_jwt': 'compact_jwt_value'}]}, 'upgrade': {'package': 'package_value', 'parsed_version': {}, 'distribution': {'cpe_uri': 'cpe_uri_value', 'classification': 'classification_value', 'severity': 'severity_value', 'cve': ['cve_value1', 'cve_value2']}, 'windows_update': {'identity': {'update_id': 'update_id_value', 'revision': 879}, 'title': 'title_value', 'description': 'description_value', 'categories': [{'category_id': 'category_id_value', 'name': 'name_value'}], 'kb_article_ids': ['kb_article_ids_value1', 'kb_article_ids_value2'], 'support_url': 'support_url_value', 'last_published_timestamp': {}}}, 'compliance': {'non_compliant_files': [{'path': 'path_value', 'display_command': 'display_command_value', 'reason': 'reason_value'}], 'non_compliance_reason': 'non_compliance_reason_value', 'version': {'cpe_uri': 'cpe_uri_value', 'benchmark_document': 'benchmark_document_value', 'version': 'version_value'}}, 'dsse_attestation': {'envelope': {'payload': b'payload_blob', 'payload_type': 'payload_type_value', 'signatures': [{'sig': b'sig_blob', 'keyid': 'keyid_value'}]}, 'statement': {}}, 'sbom_reference': {'payload': {'type_': 'type__value', 'predicate_type': 'predicate_type_value', 'subject': {}, 'predicate': {'referrer_id': 'referrer_id_value', 'location': 'location_value', 'mime_type': 'mime_type_value', 'digest': {}}}, 'payload_type': 'payload_type_value', 'signatures': {}}, 'envelope': {}} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = grafeas.UpdateOccurrenceRequest.meta.fields["occurrence"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["occurrence"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["occurrence"][field])): + del request_init["occurrence"][field][i][subfield] + else: + del request_init["occurrence"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Occurrence( + name='name_value', + resource_uri='resource_uri_value', + note_name='note_name_value', + kind=common.NoteKind.VULNERABILITY, + remediation='remediation_value', + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Occurrence.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_occurrence(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Occurrence) + assert response.name == 'name_value' + assert response.resource_uri == 'resource_uri_value' + assert response.note_name == 'note_name_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.remediation == 'remediation_value' + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_occurrence_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "post_update_occurrence") as post, \ + mock.patch.object(transports.GrafeasRestInterceptor, "pre_update_occurrence") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.UpdateOccurrenceRequest.pb(grafeas.UpdateOccurrenceRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.Occurrence.to_json(grafeas.Occurrence()) + req.return_value.content = return_value + + request = grafeas.UpdateOccurrenceRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.Occurrence() + + client.update_occurrence(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_occurrence_note_rest_bad_request(request_type=grafeas.GetOccurrenceNoteRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/occurrences/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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_occurrence_note(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.GetOccurrenceNoteRequest, + dict, +]) +def test_get_occurrence_note_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/occurrences/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 = grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_occurrence_note(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == 'name_value' + assert response.short_description == 'short_description_value' + assert response.long_description == 'long_description_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ['related_note_names_value'] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_occurrence_note_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "post_get_occurrence_note") as post, \ + mock.patch.object(transports.GrafeasRestInterceptor, "pre_get_occurrence_note") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.GetOccurrenceNoteRequest.pb(grafeas.GetOccurrenceNoteRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.Note.to_json(grafeas.Note()) + req.return_value.content = return_value + + request = grafeas.GetOccurrenceNoteRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.Note() + + client.get_occurrence_note(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_note_rest_bad_request(request_type=grafeas.GetNoteRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/notes/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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.get_note(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.GetNoteRequest, + dict, +]) +def test_get_note_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/notes/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 = grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_note(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == 'name_value' + assert response.short_description == 'short_description_value' + assert response.long_description == 'long_description_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ['related_note_names_value'] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_note_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "post_get_note") as post, \ + mock.patch.object(transports.GrafeasRestInterceptor, "pre_get_note") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.GetNoteRequest.pb(grafeas.GetNoteRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.Note.to_json(grafeas.Note()) + req.return_value.content = return_value + + request = grafeas.GetNoteRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.Note() + + client.get_note(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_notes_rest_bad_request(request_type=grafeas.ListNotesRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1'} + 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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_notes(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.ListNotesRequest, + dict, +]) +def test_list_notes_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.ListNotesResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.ListNotesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_notes(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListNotesPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_notes_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "post_list_notes") as post, \ + mock.patch.object(transports.GrafeasRestInterceptor, "pre_list_notes") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.ListNotesRequest.pb(grafeas.ListNotesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.ListNotesResponse.to_json(grafeas.ListNotesResponse()) + req.return_value.content = return_value + + request = grafeas.ListNotesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.ListNotesResponse() + + client.list_notes(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_delete_note_rest_bad_request(request_type=grafeas.DeleteNoteRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/notes/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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.delete_note(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.DeleteNoteRequest, + dict, +]) +def test_delete_note_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/notes/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 = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + 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_note(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_note_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "pre_delete_note") as pre: + pre.assert_not_called() + pb_message = grafeas.DeleteNoteRequest.pb(grafeas.DeleteNoteRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + + request = grafeas.DeleteNoteRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_note(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_create_note_rest_bad_request(request_type=grafeas.CreateNoteRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1'} + 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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.create_note(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.CreateNoteRequest, + dict, +]) +def test_create_note_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1'} + request_init["note"] = {'name': 'name_value', 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'kind': 1, 'related_url': [{'url': 'url_value', 'label': 'label_value'}], 'expiration_time': {'seconds': 751, 'nanos': 543}, 'create_time': {}, 'update_time': {}, 'related_note_names': ['related_note_names_value1', 'related_note_names_value2'], 'vulnerability': {'cvss_score': 0.1082, 'severity': 1, 'details': [{'severity_name': 'severity_name_value', 'description': 'description_value', 'package_type': 'package_type_value', 'affected_cpe_uri': 'affected_cpe_uri_value', 'affected_package': 'affected_package_value', 'affected_version_start': {'epoch': 527, 'name': 'name_value', 'revision': 'revision_value', 'inclusive': True, 'kind': 1, 'full_name': 'full_name_value'}, 'affected_version_end': {}, 'fixed_cpe_uri': 'fixed_cpe_uri_value', 'fixed_package': 'fixed_package_value', 'fixed_version': {}, 'is_obsolete': True, 'source_update_time': {}, 'source': 'source_value', 'vendor': 'vendor_value'}], 'cvss_v3': {'base_score': 0.1046, 'exploitability_score': 0.21580000000000002, 'impact_score': 0.1273, 'attack_vector': 1, 'attack_complexity': 1, 'privileges_required': 1, 'user_interaction': 1, 'scope': 1, 'confidentiality_impact': 1, 'integrity_impact': 1, 'availability_impact': 1}, 'windows_details': [{'cpe_uri': 'cpe_uri_value', 'name': 'name_value', 'description': 'description_value', 'fixing_kbs': [{'name': 'name_value', 'url': 'url_value'}]}], 'source_update_time': {}, 'cvss_version': 1, 'cvss_v2': {'base_score': 0.1046, 'exploitability_score': 0.21580000000000002, 'impact_score': 0.1273, 'attack_vector': 1, 'attack_complexity': 1, 'authentication': 1, 'privileges_required': 1, 'user_interaction': 1, 'scope': 1, 'confidentiality_impact': 1, 'integrity_impact': 1, 'availability_impact': 1}}, 'build': {'builder_version': 'builder_version_value'}, 'image': {'resource_url': 'resource_url_value', 'fingerprint': {'v1_name': 'v1_name_value', 'v2_blob': ['v2_blob_value1', 'v2_blob_value2'], 'v2_name': 'v2_name_value'}}, 'package': {'name': 'name_value', 'distribution': [{'cpe_uri': 'cpe_uri_value', 'architecture': 1, 'latest_version': {}, 'maintainer': 'maintainer_value', 'url': 'url_value', 'description': 'description_value'}], 'package_type': 'package_type_value', 'cpe_uri': 'cpe_uri_value', 'architecture': 1, 'version': {}, 'maintainer': 'maintainer_value', 'url': 'url_value', 'description': 'description_value', 'license_': {'expression': 'expression_value', 'comments': 'comments_value'}, 'digest': [{'algo': 'algo_value', 'digest_bytes': b'digest_bytes_blob'}]}, 'deployment': {'resource_uri': ['resource_uri_value1', 'resource_uri_value2']}, 'discovery': {'analysis_kind': 1}, 'attestation': {'hint': {'human_readable_name': 'human_readable_name_value'}}, 'upgrade': {'package': 'package_value', 'version': {}, 'distributions': [{'cpe_uri': 'cpe_uri_value', 'classification': 'classification_value', 'severity': 'severity_value', 'cve': ['cve_value1', 'cve_value2']}], 'windows_update': {'identity': {'update_id': 'update_id_value', 'revision': 879}, 'title': 'title_value', 'description': 'description_value', 'categories': [{'category_id': 'category_id_value', 'name': 'name_value'}], 'kb_article_ids': ['kb_article_ids_value1', 'kb_article_ids_value2'], 'support_url': 'support_url_value', 'last_published_timestamp': {}}}, 'compliance': {'title': 'title_value', 'description': 'description_value', 'version': [{'cpe_uri': 'cpe_uri_value', 'benchmark_document': 'benchmark_document_value', 'version': 'version_value'}], 'rationale': 'rationale_value', 'remediation': 'remediation_value', 'cis_benchmark': {'profile_level': 1384, 'severity': 1}, 'scan_instructions': b'scan_instructions_blob', 'impact': 'impact_value'}, 'dsse_attestation': {'hint': {'human_readable_name': 'human_readable_name_value'}}, 'vulnerability_assessment': {'title': 'title_value', 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'language_code': 'language_code_value', 'publisher': {'name': 'name_value', 'issuing_authority': 'issuing_authority_value', 'publisher_namespace': 'publisher_namespace_value'}, 'product': {'name': 'name_value', 'id': 'id_value', 'generic_uri': 'generic_uri_value'}, 'assessment': {'cve': 'cve_value', 'vulnerability_id': 'vulnerability_id_value', 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'related_uris': {}, 'state': 1, 'impacts': ['impacts_value1', 'impacts_value2'], 'justification': {'justification_type': 1, 'details': 'details_value'}, 'remediations': [{'remediation_type': 1, 'details': 'details_value', 'remediation_uri': {}}]}}, 'sbom_reference': {'format_': 'format__value', 'version': 'version_value'}} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = grafeas.CreateNoteRequest.meta.fields["note"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["note"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["note"][field])): + del request_init["note"][field][i][subfield] + else: + del request_init["note"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_note(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == 'name_value' + assert response.short_description == 'short_description_value' + assert response.long_description == 'long_description_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ['related_note_names_value'] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_note_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "post_create_note") as post, \ + mock.patch.object(transports.GrafeasRestInterceptor, "pre_create_note") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.CreateNoteRequest.pb(grafeas.CreateNoteRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.Note.to_json(grafeas.Note()) + req.return_value.content = return_value + + request = grafeas.CreateNoteRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.Note() + + client.create_note(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_batch_create_notes_rest_bad_request(request_type=grafeas.BatchCreateNotesRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1'} + 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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.batch_create_notes(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.BatchCreateNotesRequest, + dict, +]) +def test_batch_create_notes_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1'} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.BatchCreateNotesResponse( + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.BatchCreateNotesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.batch_create_notes(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.BatchCreateNotesResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_create_notes_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "post_batch_create_notes") as post, \ + mock.patch.object(transports.GrafeasRestInterceptor, "pre_batch_create_notes") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.BatchCreateNotesRequest.pb(grafeas.BatchCreateNotesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.BatchCreateNotesResponse.to_json(grafeas.BatchCreateNotesResponse()) + req.return_value.content = return_value + + request = grafeas.BatchCreateNotesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.BatchCreateNotesResponse() + + client.batch_create_notes(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_note_rest_bad_request(request_type=grafeas.UpdateNoteRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/notes/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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.update_note(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.UpdateNoteRequest, + dict, +]) +def test_update_note_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/notes/sample2'} + request_init["note"] = {'name': 'name_value', 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'kind': 1, 'related_url': [{'url': 'url_value', 'label': 'label_value'}], 'expiration_time': {'seconds': 751, 'nanos': 543}, 'create_time': {}, 'update_time': {}, 'related_note_names': ['related_note_names_value1', 'related_note_names_value2'], 'vulnerability': {'cvss_score': 0.1082, 'severity': 1, 'details': [{'severity_name': 'severity_name_value', 'description': 'description_value', 'package_type': 'package_type_value', 'affected_cpe_uri': 'affected_cpe_uri_value', 'affected_package': 'affected_package_value', 'affected_version_start': {'epoch': 527, 'name': 'name_value', 'revision': 'revision_value', 'inclusive': True, 'kind': 1, 'full_name': 'full_name_value'}, 'affected_version_end': {}, 'fixed_cpe_uri': 'fixed_cpe_uri_value', 'fixed_package': 'fixed_package_value', 'fixed_version': {}, 'is_obsolete': True, 'source_update_time': {}, 'source': 'source_value', 'vendor': 'vendor_value'}], 'cvss_v3': {'base_score': 0.1046, 'exploitability_score': 0.21580000000000002, 'impact_score': 0.1273, 'attack_vector': 1, 'attack_complexity': 1, 'privileges_required': 1, 'user_interaction': 1, 'scope': 1, 'confidentiality_impact': 1, 'integrity_impact': 1, 'availability_impact': 1}, 'windows_details': [{'cpe_uri': 'cpe_uri_value', 'name': 'name_value', 'description': 'description_value', 'fixing_kbs': [{'name': 'name_value', 'url': 'url_value'}]}], 'source_update_time': {}, 'cvss_version': 1, 'cvss_v2': {'base_score': 0.1046, 'exploitability_score': 0.21580000000000002, 'impact_score': 0.1273, 'attack_vector': 1, 'attack_complexity': 1, 'authentication': 1, 'privileges_required': 1, 'user_interaction': 1, 'scope': 1, 'confidentiality_impact': 1, 'integrity_impact': 1, 'availability_impact': 1}}, 'build': {'builder_version': 'builder_version_value'}, 'image': {'resource_url': 'resource_url_value', 'fingerprint': {'v1_name': 'v1_name_value', 'v2_blob': ['v2_blob_value1', 'v2_blob_value2'], 'v2_name': 'v2_name_value'}}, 'package': {'name': 'name_value', 'distribution': [{'cpe_uri': 'cpe_uri_value', 'architecture': 1, 'latest_version': {}, 'maintainer': 'maintainer_value', 'url': 'url_value', 'description': 'description_value'}], 'package_type': 'package_type_value', 'cpe_uri': 'cpe_uri_value', 'architecture': 1, 'version': {}, 'maintainer': 'maintainer_value', 'url': 'url_value', 'description': 'description_value', 'license_': {'expression': 'expression_value', 'comments': 'comments_value'}, 'digest': [{'algo': 'algo_value', 'digest_bytes': b'digest_bytes_blob'}]}, 'deployment': {'resource_uri': ['resource_uri_value1', 'resource_uri_value2']}, 'discovery': {'analysis_kind': 1}, 'attestation': {'hint': {'human_readable_name': 'human_readable_name_value'}}, 'upgrade': {'package': 'package_value', 'version': {}, 'distributions': [{'cpe_uri': 'cpe_uri_value', 'classification': 'classification_value', 'severity': 'severity_value', 'cve': ['cve_value1', 'cve_value2']}], 'windows_update': {'identity': {'update_id': 'update_id_value', 'revision': 879}, 'title': 'title_value', 'description': 'description_value', 'categories': [{'category_id': 'category_id_value', 'name': 'name_value'}], 'kb_article_ids': ['kb_article_ids_value1', 'kb_article_ids_value2'], 'support_url': 'support_url_value', 'last_published_timestamp': {}}}, 'compliance': {'title': 'title_value', 'description': 'description_value', 'version': [{'cpe_uri': 'cpe_uri_value', 'benchmark_document': 'benchmark_document_value', 'version': 'version_value'}], 'rationale': 'rationale_value', 'remediation': 'remediation_value', 'cis_benchmark': {'profile_level': 1384, 'severity': 1}, 'scan_instructions': b'scan_instructions_blob', 'impact': 'impact_value'}, 'dsse_attestation': {'hint': {'human_readable_name': 'human_readable_name_value'}}, 'vulnerability_assessment': {'title': 'title_value', 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'language_code': 'language_code_value', 'publisher': {'name': 'name_value', 'issuing_authority': 'issuing_authority_value', 'publisher_namespace': 'publisher_namespace_value'}, 'product': {'name': 'name_value', 'id': 'id_value', 'generic_uri': 'generic_uri_value'}, 'assessment': {'cve': 'cve_value', 'vulnerability_id': 'vulnerability_id_value', 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'related_uris': {}, 'state': 1, 'impacts': ['impacts_value1', 'impacts_value2'], 'justification': {'justification_type': 1, 'details': 'details_value'}, 'remediations': [{'remediation_type': 1, 'details': 'details_value', 'remediation_uri': {}}]}}, 'sbom_reference': {'format_': 'format__value', 'version': 'version_value'}} + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = grafeas.UpdateNoteRequest.meta.fields["note"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["note"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + {"field": field, "subfield": subfield, "is_repeated": is_repeated} + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["note"][field])): + del request_init["note"][field][i][subfield] + else: + del request_init["note"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), 'request') as req: + # Designate an appropriate value for the returned response. + return_value = grafeas.Note( + name='name_value', + short_description='short_description_value', + long_description='long_description_value', + kind=common.NoteKind.VULNERABILITY, + related_note_names=['related_note_names_value'], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.Note.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_note(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, grafeas.Note) + assert response.name == 'name_value' + assert response.short_description == 'short_description_value' + assert response.long_description == 'long_description_value' + assert response.kind == common.NoteKind.VULNERABILITY + assert response.related_note_names == ['related_note_names_value'] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_note_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "post_update_note") as post, \ + mock.patch.object(transports.GrafeasRestInterceptor, "pre_update_note") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.UpdateNoteRequest.pb(grafeas.UpdateNoteRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.Note.to_json(grafeas.Note()) + req.return_value.content = return_value + + request = grafeas.UpdateNoteRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.Note() + + client.update_note(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_note_occurrences_rest_bad_request(request_type=grafeas.ListNoteOccurrencesRequest): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/notes/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 = mock.Mock() + json_return_value = '' + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + client.list_note_occurrences(request) + + +@pytest.mark.parametrize("request_type", [ + grafeas.ListNoteOccurrencesRequest, + dict, +]) +def test_list_note_occurrences_rest_call_success(request_type): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/notes/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 = grafeas.ListNoteOccurrencesResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = grafeas.ListNoteOccurrencesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_note_occurrences(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListNoteOccurrencesPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_note_occurrences_rest_interceptors(null_interceptor): + transport = transports.GrafeasRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), + ) + client = GrafeasClient(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.GrafeasRestInterceptor, "post_list_note_occurrences") as post, \ + mock.patch.object(transports.GrafeasRestInterceptor, "pre_list_note_occurrences") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = grafeas.ListNoteOccurrencesRequest.pb(grafeas.ListNoteOccurrencesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + return_value = grafeas.ListNoteOccurrencesResponse.to_json(grafeas.ListNoteOccurrencesResponse()) + req.return_value.content = return_value + + request = grafeas.ListNoteOccurrencesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = grafeas.ListNoteOccurrencesResponse() + + client.list_note_occurrences(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + +def test_initialize_client_w_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_occurrence_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence), + '__call__') as call: + client.get_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_occurrences_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_occurrences), + '__call__') as call: + client.list_occurrences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListOccurrencesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_occurrence_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_occurrence), + '__call__') as call: + client.delete_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.DeleteOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_occurrence_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_occurrence), + '__call__') as call: + client.create_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.CreateOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_occurrences_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_occurrences), + '__call__') as call: + client.batch_create_occurrences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.BatchCreateOccurrencesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_occurrence_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_occurrence), + '__call__') as call: + client.update_occurrence(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.UpdateOccurrenceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_occurrence_note_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_occurrence_note), + '__call__') as call: + client.get_occurrence_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetOccurrenceNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_note_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_note), + '__call__') as call: + client.get_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.GetNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_notes_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_notes), + '__call__') as call: + client.list_notes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListNotesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_note_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_note), + '__call__') as call: + client.delete_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.DeleteNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_note_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_note), + '__call__') as call: + client.create_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.CreateNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_notes_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_notes), + '__call__') as call: + client.batch_create_notes(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.BatchCreateNotesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_note_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_note), + '__call__') as call: + client.update_note(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.UpdateNoteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_note_occurrences_empty_call_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_note_occurrences), + '__call__') as call: + client.list_note_occurrences(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = grafeas.ListNoteOccurrencesRequest() + + assert args[0] == request_msg + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.GrafeasGrpcTransport, + ) + +def test_grafeas_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.GrafeasTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_grafeas_base_transport(): + # Instantiate the base transport. + with mock.patch('grafeas.grafeas_v1.services.grafeas.transports.GrafeasTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.GrafeasTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'get_occurrence', + 'list_occurrences', + 'delete_occurrence', + 'create_occurrence', + 'batch_create_occurrences', + 'update_occurrence', + 'get_occurrence_note', + 'get_note', + 'list_notes', + 'delete_note', + 'create_note', + 'batch_create_notes', + 'update_note', + 'list_note_occurrences', + ) + 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_grafeas_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('grafeas.grafeas_v1.services.grafeas.transports.GrafeasTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.GrafeasTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( +), + quota_project_id="octopus", + ) + + +def test_grafeas_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('grafeas.grafeas_v1.services.grafeas.transports.GrafeasTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.GrafeasTransport() + adc.assert_called_once() + + +def test_grafeas_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) + GrafeasClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.GrafeasGrpcTransport, + transports.GrafeasGrpcAsyncIOTransport, + ], +) +def test_grafeas_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=(), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.GrafeasGrpcTransport, + transports.GrafeasGrpcAsyncIOTransport, + transports.GrafeasRestTransport, + ], +) +def test_grafeas_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.GrafeasGrpcTransport, grpc_helpers), + (transports.GrafeasGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_grafeas_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( + "containeranalysis.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( +), + scopes=["1", "2"], + default_host="containeranalysis.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.GrafeasGrpcTransport, transports.GrafeasGrpcAsyncIOTransport]) +def test_grafeas_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_grafeas_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.GrafeasRestTransport ( + 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_grafeas_host_no_port(transport_name): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='containeranalysis.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'containeranalysis.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://containeranalysis.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_grafeas_host_with_port(transport_name): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='containeranalysis.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'containeranalysis.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://containeranalysis.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_grafeas_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = GrafeasClient( + credentials=creds1, + transport=transport_name, + ) + client2 = GrafeasClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_occurrence._session + session2 = client2.transport.get_occurrence._session + assert session1 != session2 + session1 = client1.transport.list_occurrences._session + session2 = client2.transport.list_occurrences._session + assert session1 != session2 + session1 = client1.transport.delete_occurrence._session + session2 = client2.transport.delete_occurrence._session + assert session1 != session2 + session1 = client1.transport.create_occurrence._session + session2 = client2.transport.create_occurrence._session + assert session1 != session2 + session1 = client1.transport.batch_create_occurrences._session + session2 = client2.transport.batch_create_occurrences._session + assert session1 != session2 + session1 = client1.transport.update_occurrence._session + session2 = client2.transport.update_occurrence._session + assert session1 != session2 + session1 = client1.transport.get_occurrence_note._session + session2 = client2.transport.get_occurrence_note._session + assert session1 != session2 + session1 = client1.transport.get_note._session + session2 = client2.transport.get_note._session + assert session1 != session2 + session1 = client1.transport.list_notes._session + session2 = client2.transport.list_notes._session + assert session1 != session2 + session1 = client1.transport.delete_note._session + session2 = client2.transport.delete_note._session + assert session1 != session2 + session1 = client1.transport.create_note._session + session2 = client2.transport.create_note._session + assert session1 != session2 + session1 = client1.transport.batch_create_notes._session + session2 = client2.transport.batch_create_notes._session + assert session1 != session2 + session1 = client1.transport.update_note._session + session2 = client2.transport.update_note._session + assert session1 != session2 + session1 = client1.transport.list_note_occurrences._session + session2 = client2.transport.list_note_occurrences._session + assert session1 != session2 +def test_grafeas_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.GrafeasGrpcTransport( + 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_grafeas_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.GrafeasGrpcAsyncIOTransport( + 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.GrafeasGrpcTransport, transports.GrafeasGrpcAsyncIOTransport]) +def test_grafeas_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.GrafeasGrpcTransport, transports.GrafeasGrpcAsyncIOTransport]) +def test_grafeas_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_note_path(): + project = "squid" + note = "clam" + expected = "projects/{project}/notes/{note}".format(project=project, note=note, ) + actual = GrafeasClient.note_path(project, note) + assert expected == actual + + +def test_parse_note_path(): + expected = { + "project": "whelk", + "note": "octopus", + } + path = GrafeasClient.note_path(**expected) + + # Check that the path construction is reversible. + actual = GrafeasClient.parse_note_path(path) + assert expected == actual + +def test_occurrence_path(): + project = "oyster" + occurrence = "nudibranch" + expected = "projects/{project}/occurrences/{occurrence}".format(project=project, occurrence=occurrence, ) + actual = GrafeasClient.occurrence_path(project, occurrence) + assert expected == actual + + +def test_parse_occurrence_path(): + expected = { + "project": "cuttlefish", + "occurrence": "mussel", + } + path = GrafeasClient.occurrence_path(**expected) + + # Check that the path construction is reversible. + actual = GrafeasClient.parse_occurrence_path(path) + assert expected == actual + +def test_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = GrafeasClient.project_path(project) + assert expected == actual + + +def test_parse_project_path(): + expected = { + "project": "nautilus", + } + path = GrafeasClient.project_path(**expected) + + # Check that the path construction is reversible. + actual = GrafeasClient.parse_project_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = GrafeasClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = GrafeasClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = GrafeasClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format(folder=folder, ) + actual = GrafeasClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = GrafeasClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = GrafeasClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format(organization=organization, ) + actual = GrafeasClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = GrafeasClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = GrafeasClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format(project=project, ) + actual = GrafeasClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = GrafeasClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = GrafeasClient.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 = GrafeasClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = GrafeasClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = GrafeasClient.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.GrafeasTransport, '_prep_wrapped_messages') as prep: + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.GrafeasTransport, '_prep_wrapped_messages') as prep: + transport_class = GrafeasClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_grpc(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc" + ) + with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = GrafeasAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio" + ) + with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close_rest(): + client = GrafeasClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + with mock.patch.object(type(getattr(client.transport, "_session")), "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 = GrafeasClient( + 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", [ + (GrafeasClient, transports.GrafeasGrpcTransport), + (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport), +]) +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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) From 661ac2ca07d5a785fe51afd9608c83a673a8df87 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Thu, 24 Oct 2024 22:23:22 +0000 Subject: [PATCH 2/3] update replacement for docs/index.rst --- .../docs-index-rst-for-unversioned-apis.yaml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/scripts/client-post-processing/docs-index-rst-for-unversioned-apis.yaml b/scripts/client-post-processing/docs-index-rst-for-unversioned-apis.yaml index 122e91810bbd..21643914a677 100644 --- a/scripts/client-post-processing/docs-index-rst-for-unversioned-apis.yaml +++ b/scripts/client-post-processing/docs-index-rst-for-unversioned-apis.yaml @@ -62,8 +62,8 @@ replacements: .. toctree:: :maxdepth: 2 - type/services - type/types + type/services_ + type/types_ after: | .. include:: README.rst @@ -74,6 +74,7 @@ replacements: .. toctree:: :maxdepth: 2 + type/services_ type/types_ @@ -96,8 +97,8 @@ replacements: .. toctree:: :maxdepth: 2 - type/services - type/types + type/services_ + type/types_ after: | .. include:: README.rst @@ -108,6 +109,7 @@ replacements: .. toctree:: :maxdepth: 2 + calendar/services_ calendar/types_ docs/services_ @@ -143,8 +145,8 @@ replacements: .. toctree:: :maxdepth: 2 - type/services - type/types + type/services_ + type/types_ after: | .. include:: README.rst @@ -155,6 +157,7 @@ replacements: .. toctree:: :maxdepth: 2 + type/services_ type/types_ From 7709648d5fe9ad0e4610163bde22e75f17401d7c Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Thu, 24 Oct 2024 22:57:37 +0000 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20po?= =?UTF-8?q?st-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- .../v1beta/.coveragerc | 13 - .../v1beta/.flake8 | 33 - .../v1beta/MANIFEST.in | 2 - .../v1beta/README.rst | 49 - .../v1beta/docs/_static/custom.css | 3 - .../v1beta/docs/conf.py | 376 - .../v1beta/docs/index.rst | 7 - .../promotions_service.rst | 10 - .../merchant_promotions_v1beta/services_.rst | 6 - .../merchant_promotions_v1beta/types_.rst | 6 - .../shopping/merchant_promotions/__init__.py | 51 - .../merchant_promotions/gapic_version.py | 16 - .../shopping/merchant_promotions/py.typed | 2 - .../merchant_promotions_v1beta/__init__.py | 52 - .../gapic_metadata.json | 73 - .../gapic_version.py | 16 - .../merchant_promotions_v1beta/py.typed | 2 - .../services/__init__.py | 15 - .../services/promotions_service/__init__.py | 22 - .../promotions_service/async_client.py | 584 - .../services/promotions_service/client.py | 939 -- .../services/promotions_service/pagers.py | 162 - .../promotions_service/transports/README.rst | 9 - .../promotions_service/transports/__init__.py | 38 - .../promotions_service/transports/base.py | 182 - .../promotions_service/transports/grpc.py | 334 - .../transports/grpc_asyncio.py | 365 - .../promotions_service/transports/rest.py | 511 - .../transports/rest_base.py | 212 - .../types/__init__.py | 46 - .../types/promotions.py | 277 - .../types/promotions_common.py | 671 - .../v1beta/mypy.ini | 3 - .../v1beta/noxfile.py | 280 - ..._promotions_service_get_promotion_async.py | 52 - ...d_promotions_service_get_promotion_sync.py | 52 - ...omotions_service_insert_promotion_async.py | 60 - ...romotions_service_insert_promotion_sync.py | 60 - ...romotions_service_list_promotions_async.py | 53 - ...promotions_service_list_promotions_sync.py | 53 - ...e.shopping.merchant.promotions.v1beta.json | 490 - ...xup_merchant_promotions_v1beta_keywords.py | 178 - .../v1beta/setup.py | 99 - .../v1beta/testing/constraints-3.10.txt | 7 - .../v1beta/testing/constraints-3.11.txt | 7 - .../v1beta/testing/constraints-3.12.txt | 7 - .../v1beta/testing/constraints-3.7.txt | 11 - .../v1beta/testing/constraints-3.8.txt | 7 - .../v1beta/testing/constraints-3.9.txt | 7 - .../v1beta/tests/__init__.py | 16 - .../v1beta/tests/unit/__init__.py | 16 - .../v1beta/tests/unit/gapic/__init__.py | 16 - .../merchant_promotions_v1beta/__init__.py | 16 - .../test_promotions_service.py | 3661 ----- .../v1beta/.coveragerc | 13 - .../v1beta/.flake8 | 33 - .../v1beta/MANIFEST.in | 2 - .../v1beta/README.rst | 49 - .../v1beta/docs/_static/custom.css | 3 - .../v1beta/docs/conf.py | 376 - .../v1beta/docs/index.rst | 7 - .../merchant_quota_v1beta/quota_service.rst | 10 - .../docs/merchant_quota_v1beta/services_.rst | 6 - .../docs/merchant_quota_v1beta/types_.rst | 6 - .../shopping/merchant_quota/__init__.py | 35 - .../shopping/merchant_quota/gapic_version.py | 16 - .../google/shopping/merchant_quota/py.typed | 2 - .../merchant_quota_v1beta/__init__.py | 36 - .../merchant_quota_v1beta/gapic_metadata.json | 43 - .../merchant_quota_v1beta/gapic_version.py | 16 - .../shopping/merchant_quota_v1beta/py.typed | 2 - .../services/__init__.py | 15 - .../services/quota_service/__init__.py | 22 - .../services/quota_service/async_client.py | 360 - .../services/quota_service/client.py | 716 - .../services/quota_service/pagers.py | 162 - .../quota_service/transports/README.rst | 9 - .../quota_service/transports/__init__.py | 38 - .../services/quota_service/transports/base.py | 154 - .../services/quota_service/transports/grpc.py | 272 - .../quota_service/transports/grpc_asyncio.py | 293 - .../services/quota_service/transports/rest.py | 276 - .../quota_service/transports/rest_base.py | 128 - .../merchant_quota_v1beta/types/__init__.py | 28 - .../merchant_quota_v1beta/types/quota.py | 184 - .../v1beta/mypy.ini | 3 - .../v1beta/noxfile.py | 280 - ...d_quota_service_list_quota_groups_async.py | 53 - ...ed_quota_service_list_quota_groups_sync.py | 53 - ...google.shopping.merchant.quota.v1beta.json | 176 - .../fixup_merchant_quota_v1beta_keywords.py | 176 - .../v1beta/setup.py | 98 - .../v1beta/testing/constraints-3.10.txt | 6 - .../v1beta/testing/constraints-3.11.txt | 6 - .../v1beta/testing/constraints-3.12.txt | 6 - .../v1beta/testing/constraints-3.7.txt | 10 - .../v1beta/testing/constraints-3.8.txt | 6 - .../v1beta/testing/constraints-3.9.txt | 6 - .../v1beta/tests/__init__.py | 16 - .../v1beta/tests/unit/__init__.py | 16 - .../v1beta/tests/unit/gapic/__init__.py | 16 - .../gapic/merchant_quota_v1beta/__init__.py | 16 - .../test_quota_service.py | 2403 ---- .../v1beta/.coveragerc | 13 - .../v1beta/.flake8 | 33 - .../v1beta/MANIFEST.in | 2 - .../v1beta/README.rst | 49 - .../v1beta/docs/_static/custom.css | 3 - .../v1beta/docs/conf.py | 376 - .../v1beta/docs/index.rst | 7 - .../report_service.rst | 10 - .../merchant_reports_v1beta/services_.rst | 6 - .../docs/merchant_reports_v1beta/types_.rst | 6 - .../shopping/merchant_reports/__init__.py | 63 - .../merchant_reports/gapic_version.py | 16 - .../google/shopping/merchant_reports/py.typed | 2 - .../merchant_reports_v1beta/__init__.py | 64 - .../gapic_metadata.json | 43 - .../merchant_reports_v1beta/gapic_version.py | 16 - .../shopping/merchant_reports_v1beta/py.typed | 2 - .../services/__init__.py | 15 - .../services/report_service/__init__.py | 22 - .../services/report_service/async_client.py | 361 - .../services/report_service/client.py | 708 - .../services/report_service/pagers.py | 162 - .../report_service/transports/README.rst | 9 - .../report_service/transports/__init__.py | 38 - .../report_service/transports/base.py | 154 - .../report_service/transports/grpc.py | 275 - .../report_service/transports/grpc_asyncio.py | 296 - .../report_service/transports/rest.py | 279 - .../report_service/transports/rest_base.py | 138 - .../merchant_reports_v1beta/types/__init__.py | 56 - .../merchant_reports_v1beta/types/reports.py | 2521 ---- .../v1beta/mypy.ini | 3 - .../v1beta/noxfile.py | 280 - ...a_generated_report_service_search_async.py | 54 - ...ta_generated_report_service_search_sync.py | 54 - ...ogle.shopping.merchant.reports.v1beta.json | 176 - .../fixup_merchant_reports_v1beta_keywords.py | 176 - .../v1beta/setup.py | 99 - .../v1beta/testing/constraints-3.10.txt | 7 - .../v1beta/testing/constraints-3.11.txt | 7 - .../v1beta/testing/constraints-3.12.txt | 7 - .../v1beta/testing/constraints-3.7.txt | 11 - .../v1beta/testing/constraints-3.8.txt | 7 - .../v1beta/testing/constraints-3.9.txt | 7 - .../v1beta/tests/__init__.py | 16 - .../v1beta/tests/unit/__init__.py | 16 - .../v1beta/tests/unit/gapic/__init__.py | 16 - .../gapic/merchant_reports_v1beta/__init__.py | 16 - .../test_report_service.py | 2389 --- .../google-shopping-type-py/.coveragerc | 13 - .../google-shopping-type-py/.flake8 | 33 - .../google-shopping-type-py/MANIFEST.in | 2 - .../google-shopping-type-py/README.rst | 49 - .../docs/_static/custom.css | 3 - .../google-shopping-type-py/docs/conf.py | 376 - .../google-shopping-type-py/docs/index.rst | 7 - .../docs/type/services_.rst | 4 - .../docs/type/types_.rst | 6 - .../google/shopping/type/__init__.py | 36 - .../google/shopping/type/gapic_metadata.json | 7 - .../google/shopping/type/gapic_version.py | 16 - .../google/shopping/type/py.typed | 2 - .../google/shopping/type/services/__init__.py | 15 - .../google/shopping/type/types/__init__.py | 32 - .../google/shopping/type/types/types.py | 297 - .../google-shopping-type-py/mypy.ini | 3 - .../google-shopping-type-py/noxfile.py | 280 - .../scripts/fixup_type_keywords.py | 175 - .../google-shopping-type-py/setup.py | 98 - .../testing/constraints-3.10.txt | 6 - .../testing/constraints-3.11.txt | 6 - .../testing/constraints-3.12.txt | 6 - .../testing/constraints-3.7.txt | 10 - .../testing/constraints-3.8.txt | 6 - .../testing/constraints-3.9.txt | 6 - .../google-shopping-type-py/tests/__init__.py | 16 - .../tests/unit/__init__.py | 16 - .../tests/unit/gapic/__init__.py | 16 - .../tests/unit/gapic/type/__init__.py | 16 - owl-bot-staging/grafeas/v1/.coveragerc | 13 - owl-bot-staging/grafeas/v1/.flake8 | 33 - owl-bot-staging/grafeas/v1/MANIFEST.in | 2 - owl-bot-staging/grafeas/v1/README.rst | 49 - .../grafeas/v1/docs/_static/custom.css | 3 - owl-bot-staging/grafeas/v1/docs/conf.py | 376 - .../grafeas/v1/docs/grafeas_v1/grafeas.rst | 10 - .../grafeas/v1/docs/grafeas_v1/services_.rst | 6 - .../grafeas/v1/docs/grafeas_v1/types_.rst | 6 - owl-bot-staging/grafeas/v1/docs/index.rst | 7 - .../grafeas/v1/grafeas/grafeas/__init__.py | 211 - .../v1/grafeas/grafeas/gapic_version.py | 16 - .../grafeas/v1/grafeas/grafeas/py.typed | 2 - .../grafeas/v1/grafeas/grafeas_v1/__init__.py | 212 - .../v1/grafeas/grafeas_v1/gapic_metadata.json | 238 - .../v1/grafeas/grafeas_v1/gapic_version.py | 16 - .../grafeas/v1/grafeas/grafeas_v1/py.typed | 2 - .../grafeas/grafeas_v1/services/__init__.py | 15 - .../grafeas_v1/services/grafeas/__init__.py | 22 - .../services/grafeas/async_client.py | 1836 --- .../grafeas_v1/services/grafeas/client.py | 2196 --- .../grafeas_v1/services/grafeas/pagers.py | 432 - .../services/grafeas/transports/README.rst | 9 - .../services/grafeas/transports/__init__.py | 38 - .../services/grafeas/transports/base.py | 416 - .../services/grafeas/transports/grpc.py | 631 - .../grafeas/transports/grpc_asyncio.py | 797 - .../services/grafeas/transports/rest.py | 1629 --- .../services/grafeas/transports/rest_base.py | 732 - .../v1/grafeas/grafeas_v1/types/__init__.py | 244 - .../grafeas/grafeas_v1/types/attestation.py | 148 - .../v1/grafeas/grafeas_v1/types/build.py | 115 - .../v1/grafeas/grafeas_v1/types/common.py | 295 - .../v1/grafeas/grafeas_v1/types/compliance.py | 215 - .../v1/grafeas/grafeas_v1/types/cvss.py | 464 - .../v1/grafeas/grafeas_v1/types/deployment.py | 125 - .../v1/grafeas/grafeas_v1/types/discovery.py | 281 - .../grafeas_v1/types/dsse_attestation.py | 102 - .../v1/grafeas/grafeas_v1/types/grafeas.py | 921 -- .../v1/grafeas/grafeas_v1/types/image.py | 158 - .../grafeas_v1/types/intoto_provenance.py | 248 - .../grafeas_v1/types/intoto_statement.py | 353 - .../v1/grafeas/grafeas_v1/types/package.py | 378 - .../v1/grafeas/grafeas_v1/types/provenance.py | 597 - .../v1/grafeas/grafeas_v1/types/sbom.py | 171 - .../v1/grafeas/grafeas_v1/types/severity.py | 56 - .../grafeas_v1/types/slsa_provenance.py | 258 - .../types/slsa_provenance_zero_two.py | 242 - .../v1/grafeas/grafeas_v1/types/upgrade.py | 266 - .../v1/grafeas/grafeas_v1/types/vex.py | 384 - .../grafeas/grafeas_v1/types/vulnerability.py | 594 - owl-bot-staging/grafeas/v1/mypy.ini | 3 - owl-bot-staging/grafeas/v1/noxfile.py | 280 - ...erated_grafeas_batch_create_notes_async.py | 52 - ...nerated_grafeas_batch_create_notes_sync.py | 52 - ..._grafeas_batch_create_occurrences_async.py | 52 - ...d_grafeas_batch_create_occurrences_sync.py | 52 - ..._v1_generated_grafeas_create_note_async.py | 53 - ...s_v1_generated_grafeas_create_note_sync.py | 53 - ...nerated_grafeas_create_occurrence_async.py | 52 - ...enerated_grafeas_create_occurrence_sync.py | 52 - ..._v1_generated_grafeas_delete_note_async.py | 50 - ...s_v1_generated_grafeas_delete_note_sync.py | 50 - ...nerated_grafeas_delete_occurrence_async.py | 50 - ...enerated_grafeas_delete_occurrence_sync.py | 50 - ...sis_v1_generated_grafeas_get_note_async.py | 52 - ...ysis_v1_generated_grafeas_get_note_sync.py | 52 - ..._generated_grafeas_get_occurrence_async.py | 52 - ...rated_grafeas_get_occurrence_note_async.py | 52 - ...erated_grafeas_get_occurrence_note_sync.py | 52 - ...1_generated_grafeas_get_occurrence_sync.py | 52 - ...ted_grafeas_list_note_occurrences_async.py | 53 - ...ated_grafeas_list_note_occurrences_sync.py | 53 - ...s_v1_generated_grafeas_list_notes_async.py | 53 - ...is_v1_generated_grafeas_list_notes_sync.py | 53 - ...enerated_grafeas_list_occurrences_async.py | 53 - ...generated_grafeas_list_occurrences_sync.py | 53 - ..._v1_generated_grafeas_update_note_async.py | 52 - ...s_v1_generated_grafeas_update_note_sync.py | 52 - ...nerated_grafeas_update_occurrence_async.py | 52 - ...enerated_grafeas_update_occurrence_sync.py | 52 - .../snippet_metadata_grafeas.v1.json | 2353 --- .../v1/scripts/fixup_grafeas_v1_keywords.py | 189 - owl-bot-staging/grafeas/v1/setup.py | 98 - .../grafeas/v1/testing/constraints-3.10.txt | 6 - .../grafeas/v1/testing/constraints-3.11.txt | 6 - .../grafeas/v1/testing/constraints-3.12.txt | 6 - .../grafeas/v1/testing/constraints-3.7.txt | 10 - .../grafeas/v1/testing/constraints-3.8.txt | 6 - .../grafeas/v1/testing/constraints-3.9.txt | 6 - owl-bot-staging/grafeas/v1/tests/__init__.py | 16 - .../grafeas/v1/tests/unit/__init__.py | 16 - .../grafeas/v1/tests/unit/gapic/__init__.py | 16 - .../tests/unit/gapic/grafeas_v1/__init__.py | 16 - .../unit/gapic/grafeas_v1/test_grafeas.py | 11984 ---------------- .../.flake8 | 2 +- .../CONTRIBUTING.rst | 10 +- .../MANIFEST.in | 2 +- .../docs/conf.py | 2 +- .../promotions_service/transports/rest.py | 2 +- .../noxfile.py | 20 +- .../scripts/decrypt-secrets.sh | 2 +- .../setup.py | 2 + .../testing/constraints-3.13.txt | 0 .../google-shopping-merchant-quota/.flake8 | 2 +- .../CONTRIBUTING.rst | 10 +- .../MANIFEST.in | 2 +- .../docs/conf.py | 2 +- .../services/quota_service/transports/rest.py | 2 +- .../google-shopping-merchant-quota/noxfile.py | 20 +- .../scripts/decrypt-secrets.sh | 2 +- .../google-shopping-merchant-quota/setup.py | 2 + .../testing/constraints-3.13.txt | 0 .../google-shopping-merchant-reports/.flake8 | 2 +- .../CONTRIBUTING.rst | 10 +- .../MANIFEST.in | 2 +- .../docs/conf.py | 2 +- .../report_service/transports/rest.py | 2 +- .../noxfile.py | 20 +- .../scripts/decrypt-secrets.sh | 2 +- .../google-shopping-merchant-reports/setup.py | 2 + .../testing/constraints-3.13.txt | 0 packages/google-shopping-type/.flake8 | 2 +- .../google-shopping-type/CONTRIBUTING.rst | 10 +- packages/google-shopping-type/MANIFEST.in | 2 +- packages/google-shopping-type/docs/conf.py | 2 +- packages/google-shopping-type/docs/index.rst | 1 + packages/google-shopping-type/noxfile.py | 20 +- .../scripts/decrypt-secrets.sh | 2 +- packages/google-shopping-type/setup.py | 2 + .../testing/constraints-3.13.txt | 0 packages/grafeas/.flake8 | 2 +- packages/grafeas/CONTRIBUTING.rst | 10 +- packages/grafeas/MANIFEST.in | 2 +- packages/grafeas/docs/conf.py | 2 +- .../services/grafeas/transports/rest.py | 2 +- packages/grafeas/noxfile.py | 20 +- packages/grafeas/scripts/decrypt-secrets.sh | 2 +- packages/grafeas/setup.py | 2 + .../grafeas}/testing/constraints-3.13.txt | 0 322 files changed, 135 insertions(+), 60648 deletions(-) delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/.coveragerc delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/.flake8 delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/MANIFEST.in delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/README.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/_static/custom.css delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/conf.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/index.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/promotions_service.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/services_.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/types_.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/gapic_version.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/py.typed delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_metadata.json delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_version.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/py.typed delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/async_client.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/client.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/pagers.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/README.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/base.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest_base.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions_common.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/mypy.ini delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/noxfile.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_async.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_sync.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_async.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_sync.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_async.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_sync.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1beta.json delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/scripts/fixup_merchant_promotions_v1beta_keywords.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/setup.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.10.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.11.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.12.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.7.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.8.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.9.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/.coveragerc delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/.flake8 delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/MANIFEST.in delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/README.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/_static/custom.css delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/conf.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/index.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/quota_service.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/services_.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/types_.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/gapic_version.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/py.typed delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_metadata.json delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_version.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/py.typed delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/async_client.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/client.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/pagers.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/README.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/base.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest_base.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/quota.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/mypy.ini delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/noxfile.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_async.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_sync.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1beta.json delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/scripts/fixup_merchant_quota_v1beta_keywords.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/setup.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.10.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.11.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.12.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.7.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.8.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.9.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/.coveragerc delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/.flake8 delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/MANIFEST.in delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/README.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/_static/custom.css delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/conf.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/index.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/report_service.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/services_.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/types_.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/gapic_version.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/py.typed delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_metadata.json delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_version.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/py.typed delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/async_client.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/client.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/pagers.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/README.rst delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/base.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest_base.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/reports.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/mypy.ini delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/noxfile.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_async.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_sync.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1beta.json delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/scripts/fixup_merchant_reports_v1beta_keywords.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/setup.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.10.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.11.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.12.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.7.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.8.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.9.txt delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/__init__.py delete mode 100644 owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/.coveragerc delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/.flake8 delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/MANIFEST.in delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/README.rst delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/_static/custom.css delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/conf.py delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/index.rst delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/services_.rst delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/types_.rst delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/__init__.py delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_metadata.json delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_version.py delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/py.typed delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/services/__init__.py delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/__init__.py delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/types.py delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/mypy.ini delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/noxfile.py delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/scripts/fixup_type_keywords.py delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/setup.py delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.10.txt delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.11.txt delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.12.txt delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.7.txt delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.8.txt delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.9.txt delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/__init__.py delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/__init__.py delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/gapic/__init__.py delete mode 100644 owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/gapic/type/__init__.py delete mode 100644 owl-bot-staging/grafeas/v1/.coveragerc delete mode 100644 owl-bot-staging/grafeas/v1/.flake8 delete mode 100644 owl-bot-staging/grafeas/v1/MANIFEST.in delete mode 100644 owl-bot-staging/grafeas/v1/README.rst delete mode 100644 owl-bot-staging/grafeas/v1/docs/_static/custom.css delete mode 100644 owl-bot-staging/grafeas/v1/docs/conf.py delete mode 100644 owl-bot-staging/grafeas/v1/docs/grafeas_v1/grafeas.rst delete mode 100644 owl-bot-staging/grafeas/v1/docs/grafeas_v1/services_.rst delete mode 100644 owl-bot-staging/grafeas/v1/docs/grafeas_v1/types_.rst delete mode 100644 owl-bot-staging/grafeas/v1/docs/index.rst delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas/__init__.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas/gapic_version.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas/py.typed delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/__init__.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_metadata.json delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_version.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/py.typed delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/__init__.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/__init__.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/async_client.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/client.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/pagers.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/README.rst delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/__init__.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/base.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest_base.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/__init__.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/attestation.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/build.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/common.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/compliance.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/cvss.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/deployment.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/discovery.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/dsse_attestation.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/grafeas.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/image.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_provenance.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_statement.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/package.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/provenance.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/sbom.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/severity.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance_zero_two.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/upgrade.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vex.py delete mode 100644 owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vulnerability.py delete mode 100644 owl-bot-staging/grafeas/v1/mypy.ini delete mode 100644 owl-bot-staging/grafeas/v1/noxfile.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_async.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_sync.py delete mode 100644 owl-bot-staging/grafeas/v1/samples/generated_samples/snippet_metadata_grafeas.v1.json delete mode 100644 owl-bot-staging/grafeas/v1/scripts/fixup_grafeas_v1_keywords.py delete mode 100644 owl-bot-staging/grafeas/v1/setup.py delete mode 100644 owl-bot-staging/grafeas/v1/testing/constraints-3.10.txt delete mode 100644 owl-bot-staging/grafeas/v1/testing/constraints-3.11.txt delete mode 100644 owl-bot-staging/grafeas/v1/testing/constraints-3.12.txt delete mode 100644 owl-bot-staging/grafeas/v1/testing/constraints-3.7.txt delete mode 100644 owl-bot-staging/grafeas/v1/testing/constraints-3.8.txt delete mode 100644 owl-bot-staging/grafeas/v1/testing/constraints-3.9.txt delete mode 100644 owl-bot-staging/grafeas/v1/tests/__init__.py delete mode 100644 owl-bot-staging/grafeas/v1/tests/unit/__init__.py delete mode 100644 owl-bot-staging/grafeas/v1/tests/unit/gapic/__init__.py delete mode 100644 owl-bot-staging/grafeas/v1/tests/unit/gapic/grafeas_v1/__init__.py delete mode 100644 owl-bot-staging/grafeas/v1/tests/unit/gapic/grafeas_v1/test_grafeas.py rename {owl-bot-staging/google-shopping-merchant-promotions/v1beta => packages/google-shopping-merchant-promotions}/testing/constraints-3.13.txt (100%) rename {owl-bot-staging/google-shopping-merchant-quota/v1beta => packages/google-shopping-merchant-quota}/testing/constraints-3.13.txt (100%) rename {owl-bot-staging/google-shopping-merchant-reports/v1beta => packages/google-shopping-merchant-reports}/testing/constraints-3.13.txt (100%) rename {owl-bot-staging/google-shopping-type/google-shopping-type-py => packages/google-shopping-type}/testing/constraints-3.13.txt (100%) rename {owl-bot-staging/grafeas/v1 => packages/grafeas}/testing/constraints-3.13.txt (100%) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/.coveragerc b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/.coveragerc deleted file mode 100644 index dafc77479871..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/.coveragerc +++ /dev/null @@ -1,13 +0,0 @@ -[run] -branch = True - -[report] -show_missing = True -omit = - google/shopping/merchant_promotions/__init__.py - google/shopping/merchant_promotions/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/google-shopping-merchant-promotions/v1beta/.flake8 b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/.flake8 deleted file mode 100644 index 29227d4cf419..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/.flake8 +++ /dev/null @@ -1,33 +0,0 @@ -# -*- 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/google-shopping-merchant-promotions/v1beta/MANIFEST.in b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/MANIFEST.in deleted file mode 100644 index 4000aef85aac..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -recursive-include google/shopping/merchant_promotions *.py -recursive-include google/shopping/merchant_promotions_v1beta *.py diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/README.rst b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/README.rst deleted file mode 100644 index cb2860617dd9..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/README.rst +++ /dev/null @@ -1,49 +0,0 @@ -Python Client for Google Shopping Merchant Promotions 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 Shopping Merchant Promotions 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/google-shopping-merchant-promotions/v1beta/docs/_static/custom.css b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/_static/custom.css deleted file mode 100644 index 06423be0b592..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/_static/custom.css +++ /dev/null @@ -1,3 +0,0 @@ -dl.field-list > dt { - min-width: 100px -} diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/conf.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/conf.py deleted file mode 100644 index 903cf3292f1b..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/conf.py +++ /dev/null @@ -1,376 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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-shopping-merchant-promotions 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-shopping-merchant-promotions" -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 Shopping 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-shopping-merchant-promotions-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-shopping-merchant-promotions.tex", - u"google-shopping-merchant-promotions 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-shopping-merchant-promotions", - u"Google Shopping Merchant Promotions 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-shopping-merchant-promotions", - u"google-shopping-merchant-promotions Documentation", - author, - "google-shopping-merchant-promotions", - "GAPIC library for Google Shopping Merchant Promotions 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/google-shopping-merchant-promotions/v1beta/docs/index.rst b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/index.rst deleted file mode 100644 index bd406fae2308..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/index.rst +++ /dev/null @@ -1,7 +0,0 @@ -API Reference -------------- -.. toctree:: - :maxdepth: 2 - - merchant_promotions_v1beta/services_ - merchant_promotions_v1beta/types_ diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/promotions_service.rst b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/promotions_service.rst deleted file mode 100644 index 229477aebf39..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/promotions_service.rst +++ /dev/null @@ -1,10 +0,0 @@ -PromotionsService ------------------------------------ - -.. automodule:: google.shopping.merchant_promotions_v1beta.services.promotions_service - :members: - :inherited-members: - -.. automodule:: google.shopping.merchant_promotions_v1beta.services.promotions_service.pagers - :members: - :inherited-members: diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/services_.rst b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/services_.rst deleted file mode 100644 index befbacf009f8..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/services_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Services for Google Shopping Merchant Promotions v1beta API -=========================================================== -.. toctree:: - :maxdepth: 2 - - promotions_service diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/types_.rst b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/types_.rst deleted file mode 100644 index a95c03a1e319..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/docs/merchant_promotions_v1beta/types_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Types for Google Shopping Merchant Promotions v1beta API -======================================================== - -.. automodule:: google.shopping.merchant_promotions_v1beta.types - :members: - :show-inheritance: diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/__init__.py deleted file mode 100644 index 443803dbb301..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/__init__.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.shopping.merchant_promotions import gapic_version as package_version - -__version__ = package_version.__version__ - - -from google.shopping.merchant_promotions_v1beta.services.promotions_service.client import PromotionsServiceClient -from google.shopping.merchant_promotions_v1beta.services.promotions_service.async_client import PromotionsServiceAsyncClient - -from google.shopping.merchant_promotions_v1beta.types.promotions import GetPromotionRequest -from google.shopping.merchant_promotions_v1beta.types.promotions import InsertPromotionRequest -from google.shopping.merchant_promotions_v1beta.types.promotions import ListPromotionsRequest -from google.shopping.merchant_promotions_v1beta.types.promotions import ListPromotionsResponse -from google.shopping.merchant_promotions_v1beta.types.promotions import Promotion -from google.shopping.merchant_promotions_v1beta.types.promotions_common import Attributes -from google.shopping.merchant_promotions_v1beta.types.promotions_common import PromotionStatus -from google.shopping.merchant_promotions_v1beta.types.promotions_common import CouponValueType -from google.shopping.merchant_promotions_v1beta.types.promotions_common import OfferType -from google.shopping.merchant_promotions_v1beta.types.promotions_common import ProductApplicability -from google.shopping.merchant_promotions_v1beta.types.promotions_common import RedemptionChannel -from google.shopping.merchant_promotions_v1beta.types.promotions_common import StoreApplicability - -__all__ = ('PromotionsServiceClient', - 'PromotionsServiceAsyncClient', - 'GetPromotionRequest', - 'InsertPromotionRequest', - 'ListPromotionsRequest', - 'ListPromotionsResponse', - 'Promotion', - 'Attributes', - 'PromotionStatus', - 'CouponValueType', - 'OfferType', - 'ProductApplicability', - 'RedemptionChannel', - 'StoreApplicability', -) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/gapic_version.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/gapic_version.py deleted file mode 100644 index 558c8aab67c5..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/gapic_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/py.typed b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/py.typed deleted file mode 100644 index 53f2425ea9b3..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-shopping-merchant-promotions package uses inline types. diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/__init__.py deleted file mode 100644 index d93e5699df4b..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/__init__.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.shopping.merchant_promotions_v1beta import gapic_version as package_version - -__version__ = package_version.__version__ - - -from .services.promotions_service import PromotionsServiceClient -from .services.promotions_service import PromotionsServiceAsyncClient - -from .types.promotions import GetPromotionRequest -from .types.promotions import InsertPromotionRequest -from .types.promotions import ListPromotionsRequest -from .types.promotions import ListPromotionsResponse -from .types.promotions import Promotion -from .types.promotions_common import Attributes -from .types.promotions_common import PromotionStatus -from .types.promotions_common import CouponValueType -from .types.promotions_common import OfferType -from .types.promotions_common import ProductApplicability -from .types.promotions_common import RedemptionChannel -from .types.promotions_common import StoreApplicability - -__all__ = ( - 'PromotionsServiceAsyncClient', -'Attributes', -'CouponValueType', -'GetPromotionRequest', -'InsertPromotionRequest', -'ListPromotionsRequest', -'ListPromotionsResponse', -'OfferType', -'ProductApplicability', -'Promotion', -'PromotionStatus', -'PromotionsServiceClient', -'RedemptionChannel', -'StoreApplicability', -) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_metadata.json b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_metadata.json deleted file mode 100644 index 0f9f123e2e18..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_metadata.json +++ /dev/null @@ -1,73 +0,0 @@ - { - "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", - "language": "python", - "libraryPackage": "google.shopping.merchant_promotions_v1beta", - "protoPackage": "google.shopping.merchant.promotions.v1beta", - "schema": "1.0", - "services": { - "PromotionsService": { - "clients": { - "grpc": { - "libraryClient": "PromotionsServiceClient", - "rpcs": { - "GetPromotion": { - "methods": [ - "get_promotion" - ] - }, - "InsertPromotion": { - "methods": [ - "insert_promotion" - ] - }, - "ListPromotions": { - "methods": [ - "list_promotions" - ] - } - } - }, - "grpc-async": { - "libraryClient": "PromotionsServiceAsyncClient", - "rpcs": { - "GetPromotion": { - "methods": [ - "get_promotion" - ] - }, - "InsertPromotion": { - "methods": [ - "insert_promotion" - ] - }, - "ListPromotions": { - "methods": [ - "list_promotions" - ] - } - } - }, - "rest": { - "libraryClient": "PromotionsServiceClient", - "rpcs": { - "GetPromotion": { - "methods": [ - "get_promotion" - ] - }, - "InsertPromotion": { - "methods": [ - "insert_promotion" - ] - }, - "ListPromotions": { - "methods": [ - "list_promotions" - ] - } - } - } - } - } - } -} diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_version.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_version.py deleted file mode 100644 index 558c8aab67c5..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/gapic_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/py.typed b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/py.typed deleted file mode 100644 index 53f2425ea9b3..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-shopping-merchant-promotions package uses inline types. diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/__init__.py deleted file mode 100644 index 8f6cf068242c..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/__init__.py deleted file mode 100644 index 3cebeff587b6..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 PromotionsServiceClient -from .async_client import PromotionsServiceAsyncClient - -__all__ = ( - 'PromotionsServiceClient', - 'PromotionsServiceAsyncClient', -) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/async_client.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/async_client.py deleted file mode 100644 index eeb2a4e1d005..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/async_client.py +++ /dev/null @@ -1,584 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 re -from typing import Dict, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union - -from google.shopping.merchant_promotions_v1beta 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_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - - -try: - OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.shopping.merchant_promotions_v1beta.services.promotions_service import pagers -from google.shopping.merchant_promotions_v1beta.types import promotions -from google.shopping.merchant_promotions_v1beta.types import promotions_common -from google.shopping.type.types import types -from .transports.base import PromotionsServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc_asyncio import PromotionsServiceGrpcAsyncIOTransport -from .client import PromotionsServiceClient - - -class PromotionsServiceAsyncClient: - """Service to manage promotions for products.""" - - _client: PromotionsServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = PromotionsServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = PromotionsServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = PromotionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE - _DEFAULT_UNIVERSE = PromotionsServiceClient._DEFAULT_UNIVERSE - - promotion_path = staticmethod(PromotionsServiceClient.promotion_path) - parse_promotion_path = staticmethod(PromotionsServiceClient.parse_promotion_path) - common_billing_account_path = staticmethod(PromotionsServiceClient.common_billing_account_path) - parse_common_billing_account_path = staticmethod(PromotionsServiceClient.parse_common_billing_account_path) - common_folder_path = staticmethod(PromotionsServiceClient.common_folder_path) - parse_common_folder_path = staticmethod(PromotionsServiceClient.parse_common_folder_path) - common_organization_path = staticmethod(PromotionsServiceClient.common_organization_path) - parse_common_organization_path = staticmethod(PromotionsServiceClient.parse_common_organization_path) - common_project_path = staticmethod(PromotionsServiceClient.common_project_path) - parse_common_project_path = staticmethod(PromotionsServiceClient.parse_common_project_path) - common_location_path = staticmethod(PromotionsServiceClient.common_location_path) - parse_common_location_path = staticmethod(PromotionsServiceClient.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: - PromotionsServiceAsyncClient: The constructed client. - """ - return PromotionsServiceClient.from_service_account_info.__func__(PromotionsServiceAsyncClient, 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: - PromotionsServiceAsyncClient: The constructed client. - """ - return PromotionsServiceClient.from_service_account_file.__func__(PromotionsServiceAsyncClient, 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 PromotionsServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> PromotionsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - PromotionsServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = PromotionsServiceClient.get_transport_class - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[Union[str, PromotionsServiceTransport, Callable[..., PromotionsServiceTransport]]] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the promotions service async 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 (Optional[Union[str,PromotionsServiceTransport,Callable[..., PromotionsServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the PromotionsServiceTransport constructor. - 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. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "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). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS 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. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - 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. - """ - self._client = PromotionsServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - - ) - - async def insert_promotion(self, - request: Optional[Union[promotions.InsertPromotionRequest, dict]] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> promotions.Promotion: - r"""Inserts a promotion for your Merchant Center account. - If the promotion already exists, then it updates the - promotion instead. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.shopping import merchant_promotions_v1beta - - async def sample_insert_promotion(): - # Create a client - client = merchant_promotions_v1beta.PromotionsServiceAsyncClient() - - # Initialize request argument(s) - promotion = merchant_promotions_v1beta.Promotion() - promotion.promotion_id = "promotion_id_value" - promotion.content_language = "content_language_value" - promotion.target_country = "target_country_value" - promotion.redemption_channel = ['ONLINE'] - - request = merchant_promotions_v1beta.InsertPromotionRequest( - parent="parent_value", - promotion=promotion, - data_source="data_source_value", - ) - - # Make the request - response = await client.insert_promotion(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[google.shopping.merchant_promotions_v1beta.types.InsertPromotionRequest, dict]]): - The request object. Request message for the ``InsertPromotion`` method. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.shopping.merchant_promotions_v1beta.types.Promotion: - Represents a promotion. See the following articles for - more details. - - Required promotion input attributes to pass data - validation checks are primarily defined below: - - \* [Promotions data - specification](\ https://support.google.com/merchants/answer/2906014) - \* [Local promotions data - specification](\ https://support.google.com/merchants/answer/10146130) - - After inserting, updating a promotion input, it may - take several minutes before the final promotion can - be retrieved. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, promotions.InsertPromotionRequest): - request = promotions.InsertPromotionRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[self._client._transport.insert_promotion] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def get_promotion(self, - request: Optional[Union[promotions.GetPromotionRequest, 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]] = (), - ) -> promotions.Promotion: - r"""Retrieves the promotion from your Merchant Center - account. - After inserting or updating a promotion input, it may - take several minutes before the updated promotion can be - retrieved. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.shopping import merchant_promotions_v1beta - - async def sample_get_promotion(): - # Create a client - client = merchant_promotions_v1beta.PromotionsServiceAsyncClient() - - # Initialize request argument(s) - request = merchant_promotions_v1beta.GetPromotionRequest( - name="name_value", - ) - - # Make the request - response = await client.get_promotion(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[google.shopping.merchant_promotions_v1beta.types.GetPromotionRequest, dict]]): - The request object. Request message for the ``GetPromotion`` method. - name (:class:`str`): - Required. The name of the promotion to retrieve. Format: - ``accounts/{account}/promotions/{promotions}`` - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.shopping.merchant_promotions_v1beta.types.Promotion: - Represents a promotion. See the following articles for - more details. - - Required promotion input attributes to pass data - validation checks are primarily defined below: - - \* [Promotions data - specification](\ https://support.google.com/merchants/answer/2906014) - \* [Local promotions data - specification](\ https://support.google.com/merchants/answer/10146130) - - After inserting, updating a promotion input, it may - take several minutes before the final promotion can - be retrieved. - - """ - # Create or coerce a protobuf request object. - # - Quick 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.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, promotions.GetPromotionRequest): - request = promotions.GetPromotionRequest(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._client._transport._wrapped_methods[self._client._transport.get_promotion] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def list_promotions(self, - request: Optional[Union[promotions.ListPromotionsRequest, 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.ListPromotionsAsyncPager: - r"""Lists the promotions in your Merchant Center account. The - response might contain fewer items than specified by - ``pageSize``. Rely on ``pageToken`` to determine if there are - more items to be requested. - - After inserting or updating a promotion, it may take several - minutes before the updated processed promotion can be retrieved. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.shopping import merchant_promotions_v1beta - - async def sample_list_promotions(): - # Create a client - client = merchant_promotions_v1beta.PromotionsServiceAsyncClient() - - # Initialize request argument(s) - request = merchant_promotions_v1beta.ListPromotionsRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_promotions(request=request) - - # Handle the response - async for response in page_result: - print(response) - - Args: - request (Optional[Union[google.shopping.merchant_promotions_v1beta.types.ListPromotionsRequest, dict]]): - The request object. Request message for the ``ListPromotions`` method. - parent (:class:`str`): - Required. The account to list processed promotions for. - Format: ``accounts/{account}`` - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.shopping.merchant_promotions_v1beta.services.promotions_service.pagers.ListPromotionsAsyncPager: - Response message for the ListPromotions 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.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, promotions.ListPromotionsRequest): - request = promotions.ListPromotionsRequest(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._client._transport._wrapped_methods[self._client._transport.list_promotions] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # 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.ListPromotionsAsyncPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "PromotionsServiceAsyncClient": - 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__ = ( - "PromotionsServiceAsyncClient", -) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/client.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/client.py deleted file mode 100644 index 9ef22e707369..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/client.py +++ /dev/null @@ -1,939 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.shopping.merchant_promotions_v1beta 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, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - -from google.shopping.merchant_promotions_v1beta.services.promotions_service import pagers -from google.shopping.merchant_promotions_v1beta.types import promotions -from google.shopping.merchant_promotions_v1beta.types import promotions_common -from google.shopping.type.types import types -from .transports.base import PromotionsServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import PromotionsServiceGrpcTransport -from .transports.grpc_asyncio import PromotionsServiceGrpcAsyncIOTransport -from .transports.rest import PromotionsServiceRestTransport - - -class PromotionsServiceClientMeta(type): - """Metaclass for the PromotionsService 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[PromotionsServiceTransport]] - _transport_registry["grpc"] = PromotionsServiceGrpcTransport - _transport_registry["grpc_asyncio"] = PromotionsServiceGrpcAsyncIOTransport - _transport_registry["rest"] = PromotionsServiceRestTransport - - def get_transport_class(cls, - label: Optional[str] = None, - ) -> Type[PromotionsServiceTransport]: - """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 PromotionsServiceClient(metaclass=PromotionsServiceClientMeta): - """Service to manage promotions for products.""" - - @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") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "merchantapi.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "merchantapi.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @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: - PromotionsServiceClient: 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: - PromotionsServiceClient: 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) -> PromotionsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - PromotionsServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def promotion_path(account: str,promotion: str,) -> str: - """Returns a fully-qualified promotion string.""" - return "accounts/{account}/promotions/{promotion}".format(account=account, promotion=promotion, ) - - @staticmethod - def parse_promotion_path(path: str) -> Dict[str,str]: - """Parses a promotion path into its component segments.""" - m = re.match(r"^accounts/(?P.+?)/promotions/(?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): - """Deprecated. 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. - """ - - warnings.warn("get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning) - 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 - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false").lower() - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - 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`") - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint(api_override, client_cert_source, universe_domain, use_mtls_endpoint): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): - _default_universe = PromotionsServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError(f"mTLS is not supported in any universe other than {_default_universe}.") - api_endpoint = PromotionsServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = PromotionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=universe_domain) - return api_endpoint - - @staticmethod - def _get_universe_domain(client_universe_domain: Optional[str], universe_domain_env: Optional[str]) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = PromotionsServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - @staticmethod - def _compare_universes(client_universe: str, - credentials: ga_credentials.Credentials) -> bool: - """Returns True iff the universe domains used by the client and credentials match. - - Args: - client_universe (str): The universe domain configured via the client options. - credentials (ga_credentials.Credentials): The credentials being used in the client. - - Returns: - bool: True iff client_universe matches the universe in credentials. - - Raises: - ValueError: when client_universe does not match the universe in credentials. - """ - - default_universe = PromotionsServiceClient._DEFAULT_UNIVERSE - credentials_universe = getattr(credentials, "universe_domain", default_universe) - - if client_universe != credentials_universe: - raise ValueError("The configured universe domain " - f"({client_universe}) does not match the universe domain " - f"found in the credentials ({credentials_universe}). " - "If you haven't configured the universe domain explicitly, " - f"`{default_universe}` is the default.") - return True - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - self._is_universe_domain_valid = (self._is_universe_domain_valid or - PromotionsServiceClient._compare_universes(self.universe_domain, self.transport._credentials)) - return self._is_universe_domain_valid - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[Union[str, PromotionsServiceTransport, Callable[..., PromotionsServiceTransport]]] = None, - client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the promotions 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 (Optional[Union[str,PromotionsServiceTransport,Callable[..., PromotionsServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the PromotionsServiceTransport constructor. - 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. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "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). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS 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. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - 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. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict(self._client_options) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast(client_options_lib.ClientOptions, self._client_options) - - universe_domain_opt = getattr(self._client_options, 'universe_domain', None) - - self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = PromotionsServiceClient._read_environment_variables() - self._client_cert_source = PromotionsServiceClient._get_client_cert_source(self._client_options.client_cert_source, self._use_client_cert) - self._universe_domain = PromotionsServiceClient._get_universe_domain(universe_domain_opt, self._universe_domain_env) - self._api_endpoint = None # updated below, depending on `transport` - - # Initialize the universe domain validation. - self._is_universe_domain_valid = False - - api_key_value = getattr(self._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. - transport_provided = isinstance(transport, PromotionsServiceTransport) - if transport_provided: - # transport is a PromotionsServiceTransport instance. - if credentials or self._client_options.credentials_file or api_key_value: - raise ValueError("When providing a transport instance, " - "provide its credentials directly.") - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(PromotionsServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = (self._api_endpoint or - PromotionsServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint)) - - if not transport_provided: - 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_init: Union[Type[PromotionsServiceTransport], Callable[..., PromotionsServiceTransport]] = ( - PromotionsServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., PromotionsServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - api_audience=self._client_options.api_audience, - ) - - def insert_promotion(self, - request: Optional[Union[promotions.InsertPromotionRequest, dict]] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> promotions.Promotion: - r"""Inserts a promotion for your Merchant Center account. - If the promotion already exists, then it updates the - promotion instead. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.shopping import merchant_promotions_v1beta - - def sample_insert_promotion(): - # Create a client - client = merchant_promotions_v1beta.PromotionsServiceClient() - - # Initialize request argument(s) - promotion = merchant_promotions_v1beta.Promotion() - promotion.promotion_id = "promotion_id_value" - promotion.content_language = "content_language_value" - promotion.target_country = "target_country_value" - promotion.redemption_channel = ['ONLINE'] - - request = merchant_promotions_v1beta.InsertPromotionRequest( - parent="parent_value", - promotion=promotion, - data_source="data_source_value", - ) - - # Make the request - response = client.insert_promotion(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.shopping.merchant_promotions_v1beta.types.InsertPromotionRequest, dict]): - The request object. Request message for the ``InsertPromotion`` method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.shopping.merchant_promotions_v1beta.types.Promotion: - Represents a promotion. See the following articles for - more details. - - Required promotion input attributes to pass data - validation checks are primarily defined below: - - \* [Promotions data - specification](\ https://support.google.com/merchants/answer/2906014) - \* [Local promotions data - specification](\ https://support.google.com/merchants/answer/10146130) - - After inserting, updating a promotion input, it may - take several minutes before the final promotion can - be retrieved. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, promotions.InsertPromotionRequest): - request = promotions.InsertPromotionRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.insert_promotion] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def get_promotion(self, - request: Optional[Union[promotions.GetPromotionRequest, 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]] = (), - ) -> promotions.Promotion: - r"""Retrieves the promotion from your Merchant Center - account. - After inserting or updating a promotion input, it may - take several minutes before the updated promotion can be - retrieved. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.shopping import merchant_promotions_v1beta - - def sample_get_promotion(): - # Create a client - client = merchant_promotions_v1beta.PromotionsServiceClient() - - # Initialize request argument(s) - request = merchant_promotions_v1beta.GetPromotionRequest( - name="name_value", - ) - - # Make the request - response = client.get_promotion(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.shopping.merchant_promotions_v1beta.types.GetPromotionRequest, dict]): - The request object. Request message for the ``GetPromotion`` method. - name (str): - Required. The name of the promotion to retrieve. Format: - ``accounts/{account}/promotions/{promotions}`` - - 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.shopping.merchant_promotions_v1beta.types.Promotion: - Represents a promotion. See the following articles for - more details. - - Required promotion input attributes to pass data - validation checks are primarily defined below: - - \* [Promotions data - specification](\ https://support.google.com/merchants/answer/2906014) - \* [Local promotions data - specification](\ https://support.google.com/merchants/answer/10146130) - - After inserting, updating a promotion input, it may - take several minutes before the final promotion can - be retrieved. - - """ - # Create or coerce a protobuf request object. - # - Quick 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.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, promotions.GetPromotionRequest): - request = promotions.GetPromotionRequest(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_promotion] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_promotions(self, - request: Optional[Union[promotions.ListPromotionsRequest, 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.ListPromotionsPager: - r"""Lists the promotions in your Merchant Center account. The - response might contain fewer items than specified by - ``pageSize``. Rely on ``pageToken`` to determine if there are - more items to be requested. - - After inserting or updating a promotion, it may take several - minutes before the updated processed promotion can be retrieved. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.shopping import merchant_promotions_v1beta - - def sample_list_promotions(): - # Create a client - client = merchant_promotions_v1beta.PromotionsServiceClient() - - # Initialize request argument(s) - request = merchant_promotions_v1beta.ListPromotionsRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_promotions(request=request) - - # Handle the response - for response in page_result: - print(response) - - Args: - request (Union[google.shopping.merchant_promotions_v1beta.types.ListPromotionsRequest, dict]): - The request object. Request message for the ``ListPromotions`` method. - parent (str): - Required. The account to list processed promotions for. - Format: ``accounts/{account}`` - - 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.shopping.merchant_promotions_v1beta.services.promotions_service.pagers.ListPromotionsPager: - Response message for the ListPromotions 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.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, promotions.ListPromotionsRequest): - request = promotions.ListPromotionsRequest(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_promotions] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # 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.ListPromotionsPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "PromotionsServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - - - - - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) - - -__all__ = ( - "PromotionsServiceClient", -) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/pagers.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/pagers.py deleted file mode 100644 index df04944c3a32..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/pagers.py +++ /dev/null @@ -1,162 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import retry_async as retries_async -from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator, Union -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] - OptionalAsyncRetry = Union[retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore - -from google.shopping.merchant_promotions_v1beta.types import promotions - - -class ListPromotionsPager: - """A pager for iterating through ``list_promotions`` requests. - - This class thinly wraps an initial - :class:`google.shopping.merchant_promotions_v1beta.types.ListPromotionsResponse` object, and - provides an ``__iter__`` method to iterate through its - ``promotions`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``ListPromotions`` requests and continue to iterate - through the ``promotions`` field on the - corresponding responses. - - All the usual :class:`google.shopping.merchant_promotions_v1beta.types.ListPromotionsResponse` - 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[..., promotions.ListPromotionsResponse], - request: promotions.ListPromotionsRequest, - response: promotions.ListPromotionsResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.shopping.merchant_promotions_v1beta.types.ListPromotionsRequest): - The initial request object. - response (google.shopping.merchant_promotions_v1beta.types.ListPromotionsResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = promotions.ListPromotionsRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[promotions.ListPromotionsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method(self._request, retry=self._retry, timeout=self._timeout, metadata=self._metadata) - yield self._response - - def __iter__(self) -> Iterator[promotions.Promotion]: - for page in self.pages: - yield from page.promotions - - def __repr__(self) -> str: - return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) - - -class ListPromotionsAsyncPager: - """A pager for iterating through ``list_promotions`` requests. - - This class thinly wraps an initial - :class:`google.shopping.merchant_promotions_v1beta.types.ListPromotionsResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``promotions`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``ListPromotions`` requests and continue to iterate - through the ``promotions`` field on the - corresponding responses. - - All the usual :class:`google.shopping.merchant_promotions_v1beta.types.ListPromotionsResponse` - 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[promotions.ListPromotionsResponse]], - request: promotions.ListPromotionsRequest, - response: promotions.ListPromotionsResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.shopping.merchant_promotions_v1beta.types.ListPromotionsRequest): - The initial request object. - response (google.shopping.merchant_promotions_v1beta.types.ListPromotionsResponse): - The initial response object. - retry (google.api_core.retry.AsyncRetry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = promotions.ListPromotionsRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages(self) -> AsyncIterator[promotions.ListPromotionsResponse]: - 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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) - yield self._response - def __aiter__(self) -> AsyncIterator[promotions.Promotion]: - async def async_generator(): - async for page in self.pages: - for response in page.promotions: - 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/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/README.rst b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/README.rst deleted file mode 100644 index 8e430c8e2e3a..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/README.rst +++ /dev/null @@ -1,9 +0,0 @@ - -transport inheritance structure -_______________________________ - -`PromotionsServiceTransport` is the ABC for all transports. -- public child `PromotionsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). -- public child `PromotionsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). -- private child `_BasePromotionsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). -- public child `PromotionsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/__init__.py deleted file mode 100644 index 6f04436b2cd7..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/__init__.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 PromotionsServiceTransport -from .grpc import PromotionsServiceGrpcTransport -from .grpc_asyncio import PromotionsServiceGrpcAsyncIOTransport -from .rest import PromotionsServiceRestTransport -from .rest import PromotionsServiceRestInterceptor - - -# Compile a registry of transports. -_transport_registry = OrderedDict() # type: Dict[str, Type[PromotionsServiceTransport]] -_transport_registry['grpc'] = PromotionsServiceGrpcTransport -_transport_registry['grpc_asyncio'] = PromotionsServiceGrpcAsyncIOTransport -_transport_registry['rest'] = PromotionsServiceRestTransport - -__all__ = ( - 'PromotionsServiceTransport', - 'PromotionsServiceGrpcTransport', - 'PromotionsServiceGrpcAsyncIOTransport', - 'PromotionsServiceRestTransport', - 'PromotionsServiceRestInterceptor', -) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/base.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/base.py deleted file mode 100644 index 7890c6625a55..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/base.py +++ /dev/null @@ -1,182 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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.shopping.merchant_promotions_v1beta 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.shopping.merchant_promotions_v1beta.types import promotions - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) - - -class PromotionsServiceTransport(abc.ABC): - """Abstract transport class for PromotionsService.""" - - AUTH_SCOPES = ( - 'https://www.googleapis.com/auth/content', - ) - - DEFAULT_HOST: str = 'merchantapi.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 (default: 'merchantapi.googleapis.com'). - 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 not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # 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 and not self._ignore_credentials: - 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 - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.insert_promotion: gapic_v1.method.wrap_method( - self.insert_promotion, - default_timeout=None, - client_info=client_info, - ), - self.get_promotion: gapic_v1.method.wrap_method( - self.get_promotion, - default_timeout=None, - client_info=client_info, - ), - self.list_promotions: gapic_v1.method.wrap_method( - self.list_promotions, - 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 insert_promotion(self) -> Callable[ - [promotions.InsertPromotionRequest], - Union[ - promotions.Promotion, - Awaitable[promotions.Promotion] - ]]: - raise NotImplementedError() - - @property - def get_promotion(self) -> Callable[ - [promotions.GetPromotionRequest], - Union[ - promotions.Promotion, - Awaitable[promotions.Promotion] - ]]: - raise NotImplementedError() - - @property - def list_promotions(self) -> Callable[ - [promotions.ListPromotionsRequest], - Union[ - promotions.ListPromotionsResponse, - Awaitable[promotions.ListPromotionsResponse] - ]]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ( - 'PromotionsServiceTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc.py deleted file mode 100644 index 717c5da1e20e..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc.py +++ /dev/null @@ -1,334 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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.shopping.merchant_promotions_v1beta.types import promotions -from .base import PromotionsServiceTransport, DEFAULT_CLIENT_INFO - - -class PromotionsServiceGrpcTransport(PromotionsServiceTransport): - """gRPC backend transport for PromotionsService. - - Service to manage promotions for products. - - 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 = 'merchantapi.googleapis.com', - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[grpc.Channel, Callable[..., 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 (default: 'merchantapi.googleapis.com'). - 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 a ``channel`` instance 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 a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # 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: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - 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 = 'merchantapi.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 insert_promotion(self) -> Callable[ - [promotions.InsertPromotionRequest], - promotions.Promotion]: - r"""Return a callable for the insert promotion method over gRPC. - - Inserts a promotion for your Merchant Center account. - If the promotion already exists, then it updates the - promotion instead. - - Returns: - Callable[[~.InsertPromotionRequest], - ~.Promotion]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'insert_promotion' not in self._stubs: - self._stubs['insert_promotion'] = self.grpc_channel.unary_unary( - '/google.shopping.merchant.promotions.v1beta.PromotionsService/InsertPromotion', - request_serializer=promotions.InsertPromotionRequest.serialize, - response_deserializer=promotions.Promotion.deserialize, - ) - return self._stubs['insert_promotion'] - - @property - def get_promotion(self) -> Callable[ - [promotions.GetPromotionRequest], - promotions.Promotion]: - r"""Return a callable for the get promotion method over gRPC. - - Retrieves the promotion from your Merchant Center - account. - After inserting or updating a promotion input, it may - take several minutes before the updated promotion can be - retrieved. - - Returns: - Callable[[~.GetPromotionRequest], - ~.Promotion]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_promotion' not in self._stubs: - self._stubs['get_promotion'] = self.grpc_channel.unary_unary( - '/google.shopping.merchant.promotions.v1beta.PromotionsService/GetPromotion', - request_serializer=promotions.GetPromotionRequest.serialize, - response_deserializer=promotions.Promotion.deserialize, - ) - return self._stubs['get_promotion'] - - @property - def list_promotions(self) -> Callable[ - [promotions.ListPromotionsRequest], - promotions.ListPromotionsResponse]: - r"""Return a callable for the list promotions method over gRPC. - - Lists the promotions in your Merchant Center account. The - response might contain fewer items than specified by - ``pageSize``. Rely on ``pageToken`` to determine if there are - more items to be requested. - - After inserting or updating a promotion, it may take several - minutes before the updated processed promotion can be retrieved. - - Returns: - Callable[[~.ListPromotionsRequest], - ~.ListPromotionsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_promotions' not in self._stubs: - self._stubs['list_promotions'] = self.grpc_channel.unary_unary( - '/google.shopping.merchant.promotions.v1beta.PromotionsService/ListPromotions', - request_serializer=promotions.ListPromotionsRequest.serialize, - response_deserializer=promotions.ListPromotionsResponse.deserialize, - ) - return self._stubs['list_promotions'] - - def close(self): - self.grpc_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ( - 'PromotionsServiceGrpcTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py deleted file mode 100644 index b149875ac0a0..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,365 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 inspect -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 exceptions as core_exceptions -from google.api_core import retry_async as retries -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.shopping.merchant_promotions_v1beta.types import promotions -from .base import PromotionsServiceTransport, DEFAULT_CLIENT_INFO -from .grpc import PromotionsServiceGrpcTransport - - -class PromotionsServiceGrpcAsyncIOTransport(PromotionsServiceTransport): - """gRPC AsyncIO backend transport for PromotionsService. - - Service to manage promotions for products. - - 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 = 'merchantapi.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`. - 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 = 'merchantapi.googleapis.com', - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[aio.Channel, Callable[..., 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 (default: 'merchantapi.googleapis.com'). - 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 a ``channel`` instance 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 a ``channel`` instance 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[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # 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: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - 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._wrap_with_kind = "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters - 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 insert_promotion(self) -> Callable[ - [promotions.InsertPromotionRequest], - Awaitable[promotions.Promotion]]: - r"""Return a callable for the insert promotion method over gRPC. - - Inserts a promotion for your Merchant Center account. - If the promotion already exists, then it updates the - promotion instead. - - Returns: - Callable[[~.InsertPromotionRequest], - Awaitable[~.Promotion]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if 'insert_promotion' not in self._stubs: - self._stubs['insert_promotion'] = self.grpc_channel.unary_unary( - '/google.shopping.merchant.promotions.v1beta.PromotionsService/InsertPromotion', - request_serializer=promotions.InsertPromotionRequest.serialize, - response_deserializer=promotions.Promotion.deserialize, - ) - return self._stubs['insert_promotion'] - - @property - def get_promotion(self) -> Callable[ - [promotions.GetPromotionRequest], - Awaitable[promotions.Promotion]]: - r"""Return a callable for the get promotion method over gRPC. - - Retrieves the promotion from your Merchant Center - account. - After inserting or updating a promotion input, it may - take several minutes before the updated promotion can be - retrieved. - - Returns: - Callable[[~.GetPromotionRequest], - Awaitable[~.Promotion]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_promotion' not in self._stubs: - self._stubs['get_promotion'] = self.grpc_channel.unary_unary( - '/google.shopping.merchant.promotions.v1beta.PromotionsService/GetPromotion', - request_serializer=promotions.GetPromotionRequest.serialize, - response_deserializer=promotions.Promotion.deserialize, - ) - return self._stubs['get_promotion'] - - @property - def list_promotions(self) -> Callable[ - [promotions.ListPromotionsRequest], - Awaitable[promotions.ListPromotionsResponse]]: - r"""Return a callable for the list promotions method over gRPC. - - Lists the promotions in your Merchant Center account. The - response might contain fewer items than specified by - ``pageSize``. Rely on ``pageToken`` to determine if there are - more items to be requested. - - After inserting or updating a promotion, it may take several - minutes before the updated processed promotion can be retrieved. - - Returns: - Callable[[~.ListPromotionsRequest], - Awaitable[~.ListPromotionsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_promotions' not in self._stubs: - self._stubs['list_promotions'] = self.grpc_channel.unary_unary( - '/google.shopping.merchant.promotions.v1beta.PromotionsService/ListPromotions', - request_serializer=promotions.ListPromotionsRequest.serialize, - response_deserializer=promotions.ListPromotionsResponse.deserialize, - ) - return self._stubs['list_promotions'] - - def _prep_wrapped_messages(self, client_info): - """ Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.insert_promotion: self._wrap_method( - self.insert_promotion, - default_timeout=None, - client_info=client_info, - ), - self.get_promotion: self._wrap_method( - self.get_promotion, - default_timeout=None, - client_info=client_info, - ), - self.list_promotions: self._wrap_method( - self.list_promotions, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self.grpc_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ( - 'PromotionsServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py deleted file mode 100644 index a58f56329486..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py +++ /dev/null @@ -1,511 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 -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 gapic_v1 - -from google.protobuf import json_format - -from requests import __version__ as requests_version -import dataclasses -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union -import warnings - - -from google.shopping.merchant_promotions_v1beta.types import promotions - - -from .rest_base import _BasePromotionsServiceRestTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, - grpc_version=None, - rest_version=f"requests@{requests_version}", -) - - -class PromotionsServiceRestInterceptor: - """Interceptor for PromotionsService. - - 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 PromotionsServiceRestTransport. - - .. code-block:: python - class MyCustomPromotionsServiceInterceptor(PromotionsServiceRestInterceptor): - def pre_get_promotion(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_get_promotion(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_insert_promotion(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_insert_promotion(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_list_promotions(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_list_promotions(self, response): - logging.log(f"Received response: {response}") - return response - - transport = PromotionsServiceRestTransport(interceptor=MyCustomPromotionsServiceInterceptor()) - client = PromotionsServiceClient(transport=transport) - - - """ - def pre_get_promotion(self, request: promotions.GetPromotionRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[promotions.GetPromotionRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for get_promotion - - Override in a subclass to manipulate the request or metadata - before they are sent to the PromotionsService server. - """ - return request, metadata - - def post_get_promotion(self, response: promotions.Promotion) -> promotions.Promotion: - """Post-rpc interceptor for get_promotion - - Override in a subclass to manipulate the response - after it is returned by the PromotionsService server but before - it is returned to user code. - """ - return response - - def pre_insert_promotion(self, request: promotions.InsertPromotionRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[promotions.InsertPromotionRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for insert_promotion - - Override in a subclass to manipulate the request or metadata - before they are sent to the PromotionsService server. - """ - return request, metadata - - def post_insert_promotion(self, response: promotions.Promotion) -> promotions.Promotion: - """Post-rpc interceptor for insert_promotion - - Override in a subclass to manipulate the response - after it is returned by the PromotionsService server but before - it is returned to user code. - """ - return response - - def pre_list_promotions(self, request: promotions.ListPromotionsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[promotions.ListPromotionsRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for list_promotions - - Override in a subclass to manipulate the request or metadata - before they are sent to the PromotionsService server. - """ - return request, metadata - - def post_list_promotions(self, response: promotions.ListPromotionsResponse) -> promotions.ListPromotionsResponse: - """Post-rpc interceptor for list_promotions - - Override in a subclass to manipulate the response - after it is returned by the PromotionsService server but before - it is returned to user code. - """ - return response - - -@dataclasses.dataclass -class PromotionsServiceRestStub: - _session: AuthorizedSession - _host: str - _interceptor: PromotionsServiceRestInterceptor - - -class PromotionsServiceRestTransport(_BasePromotionsServiceRestTransport): - """REST backend synchronous transport for PromotionsService. - - Service to manage promotions for products. - - 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 = 'merchantapi.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[PromotionsServiceRestInterceptor] = None, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'merchantapi.googleapis.com'). - 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 - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - url_scheme=url_scheme, - 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 PromotionsServiceRestInterceptor() - self._prep_wrapped_messages(client_info) - - class _GetPromotion(_BasePromotionsServiceRestTransport._BaseGetPromotion, PromotionsServiceRestStub): - def __hash__(self): - return hash("PromotionsServiceRestTransport.GetPromotion") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__(self, - request: promotions.GetPromotionRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> promotions.Promotion: - r"""Call the get promotion method over HTTP. - - Args: - request (~.promotions.GetPromotionRequest): - The request object. Request message for the ``GetPromotion`` method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.promotions.Promotion: - Represents a promotion. See the following articles for - more details. - - Required promotion input attributes to pass data - validation checks are primarily defined below: - - - `Promotions data - specification `__ - - `Local promotions data - specification `__ - - After inserting, updating a promotion input, it may take - several minutes before the final promotion can be - retrieved. - - """ - - http_options = _BasePromotionsServiceRestTransport._BaseGetPromotion._get_http_options() - request, metadata = self._interceptor.pre_get_promotion(request, metadata) - transcoded_request = _BasePromotionsServiceRestTransport._BaseGetPromotion._get_transcoded_request(http_options, request) - - # Jsonify the query params - query_params = _BasePromotionsServiceRestTransport._BaseGetPromotion._get_query_params_json(transcoded_request) - - # Send the request - response = PromotionsServiceRestTransport._GetPromotion._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) - - # 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 = promotions.Promotion() - pb_resp = promotions.Promotion.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_promotion(resp) - return resp - - class _InsertPromotion(_BasePromotionsServiceRestTransport._BaseInsertPromotion, PromotionsServiceRestStub): - def __hash__(self): - return hash("PromotionsServiceRestTransport.InsertPromotion") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, - ) - return response - - def __call__(self, - request: promotions.InsertPromotionRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> promotions.Promotion: - r"""Call the insert promotion method over HTTP. - - Args: - request (~.promotions.InsertPromotionRequest): - The request object. Request message for the ``InsertPromotion`` method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.promotions.Promotion: - Represents a promotion. See the following articles for - more details. - - Required promotion input attributes to pass data - validation checks are primarily defined below: - - - `Promotions data - specification `__ - - `Local promotions data - specification `__ - - After inserting, updating a promotion input, it may take - several minutes before the final promotion can be - retrieved. - - """ - - http_options = _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_http_options() - request, metadata = self._interceptor.pre_insert_promotion(request, metadata) - transcoded_request = _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_transcoded_request(http_options, request) - - body = _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_request_body_json(transcoded_request) - - # Jsonify the query params - query_params = _BasePromotionsServiceRestTransport._BaseInsertPromotion._get_query_params_json(transcoded_request) - - # Send the request - response = PromotionsServiceRestTransport._InsertPromotion._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = promotions.Promotion() - pb_resp = promotions.Promotion.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_insert_promotion(resp) - return resp - - class _ListPromotions(_BasePromotionsServiceRestTransport._BaseListPromotions, PromotionsServiceRestStub): - def __hash__(self): - return hash("PromotionsServiceRestTransport.ListPromotions") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__(self, - request: promotions.ListPromotionsRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> promotions.ListPromotionsResponse: - r"""Call the list promotions method over HTTP. - - Args: - request (~.promotions.ListPromotionsRequest): - The request object. Request message for the ``ListPromotions`` method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.promotions.ListPromotionsResponse: - Response message for the ``ListPromotions`` method. - """ - - http_options = _BasePromotionsServiceRestTransport._BaseListPromotions._get_http_options() - request, metadata = self._interceptor.pre_list_promotions(request, metadata) - transcoded_request = _BasePromotionsServiceRestTransport._BaseListPromotions._get_transcoded_request(http_options, request) - - # Jsonify the query params - query_params = _BasePromotionsServiceRestTransport._BaseListPromotions._get_query_params_json(transcoded_request) - - # Send the request - response = PromotionsServiceRestTransport._ListPromotions._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) - - # 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 = promotions.ListPromotionsResponse() - pb_resp = promotions.ListPromotionsResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_promotions(resp) - return resp - - @property - def get_promotion(self) -> Callable[ - [promotions.GetPromotionRequest], - promotions.Promotion]: - # 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._GetPromotion(self._session, self._host, self._interceptor) # type: ignore - - @property - def insert_promotion(self) -> Callable[ - [promotions.InsertPromotionRequest], - promotions.Promotion]: - # 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._InsertPromotion(self._session, self._host, self._interceptor) # type: ignore - - @property - def list_promotions(self) -> Callable[ - [promotions.ListPromotionsRequest], - promotions.ListPromotionsResponse]: - # 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._ListPromotions(self._session, self._host, self._interceptor) # type: ignore - - @property - def kind(self) -> str: - return "rest" - - def close(self): - self._session.close() - - -__all__=( - 'PromotionsServiceRestTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest_base.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest_base.py deleted file mode 100644 index aab3dec4695e..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest_base.py +++ /dev/null @@ -1,212 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 json # type: ignore -from google.api_core import path_template -from google.api_core import gapic_v1 - -from google.protobuf import json_format -from .base import PromotionsServiceTransport, DEFAULT_CLIENT_INFO - -import re -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union - - -from google.shopping.merchant_promotions_v1beta.types import promotions - - -class _BasePromotionsServiceRestTransport(PromotionsServiceTransport): - """Base REST backend transport for PromotionsService. - - Note: This class is not meant to be used directly. Use its sync and - async sub-classes instead. - - 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 = 'merchantapi.googleapis.com', - credentials: Optional[Any] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - url_scheme: str = 'https', - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - Args: - host (Optional[str]): - The hostname to connect to (default: 'merchantapi.googleapis.com'). - credentials (Optional[Any]): 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. - 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 - 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 - ) - - class _BaseGetPromotion: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'get', - 'uri': '/promotions/v1beta/{name=accounts/*/promotions/*}', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = promotions.GetPromotionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BasePromotionsServiceRestTransport._BaseGetPromotion._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseInsertPromotion: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'post', - 'uri': '/promotions/v1beta/{parent=accounts/*}/promotions:insert', - 'body': '*', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = promotions.InsertPromotionRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_request_body_json(transcoded_request): - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request['body'], - use_integers_for_enums=True - ) - return body - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BasePromotionsServiceRestTransport._BaseInsertPromotion._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseListPromotions: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'get', - 'uri': '/promotions/v1beta/{parent=accounts/*}/promotions', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = promotions.ListPromotionsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BasePromotionsServiceRestTransport._BaseListPromotions._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - -__all__=( - '_BasePromotionsServiceRestTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/__init__.py deleted file mode 100644 index aa349ec9d51f..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/__init__.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .promotions import ( - GetPromotionRequest, - InsertPromotionRequest, - ListPromotionsRequest, - ListPromotionsResponse, - Promotion, -) -from .promotions_common import ( - Attributes, - PromotionStatus, - CouponValueType, - OfferType, - ProductApplicability, - RedemptionChannel, - StoreApplicability, -) - -__all__ = ( - 'GetPromotionRequest', - 'InsertPromotionRequest', - 'ListPromotionsRequest', - 'ListPromotionsResponse', - 'Promotion', - 'Attributes', - 'PromotionStatus', - 'CouponValueType', - 'OfferType', - 'ProductApplicability', - 'RedemptionChannel', - 'StoreApplicability', -) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions.py deleted file mode 100644 index d3d9283e4324..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions.py +++ /dev/null @@ -1,277 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.shopping.merchant_promotions_v1beta.types import promotions_common -from google.shopping.type.types import types - - -__protobuf__ = proto.module( - package='google.shopping.merchant.promotions.v1beta', - manifest={ - 'Promotion', - 'InsertPromotionRequest', - 'GetPromotionRequest', - 'ListPromotionsRequest', - 'ListPromotionsResponse', - }, -) - - -class Promotion(proto.Message): - r"""Represents a promotion. See the following articles for more details. - - Required promotion input attributes to pass data validation checks - are primarily defined below: - - - `Promotions data - specification `__ - - `Local promotions data - specification `__ - - After inserting, updating a promotion input, it may take several - minutes before the final promotion can be retrieved. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - name (str): - Identifier. The name of the promotion. Format: - ``accounts/{account}/promotions/{promotion}`` - promotion_id (str): - Required. The user provided promotion ID to uniquely - identify the promotion. Follow `minimum - requirements `__ - to prevent promotion disapprovals. - content_language (str): - Required. The two-letter `ISO - 639-1 `__ language - code for the promotion. - - Promotions is only for `selected - languages `__. - target_country (str): - Required. The target country used as part of the unique - identifier. Represented as a `CLDR territory - code `__. - - Promotions are only available in selected countries, `Free - Listings and Shopping - ads `__ - `Local Inventory - ads `__ - redemption_channel (MutableSequence[google.shopping.merchant_promotions_v1beta.types.RedemptionChannel]): - Required. `Redemption - channel `__ - for the promotion. At least one channel is required. - data_source (str): - Output only. The primary data source of the - promotion. - attributes (google.shopping.merchant_promotions_v1beta.types.Attributes): - Optional. A list of promotion attributes. - custom_attributes (MutableSequence[google.shopping.type.types.CustomAttribute]): - Optional. A list of custom (merchant-provided) attributes. - It can also be used for submitting any attribute of the data - specification in its generic form (for example, - ``{ "name": "size type", "value": "regular" }``). This is - useful for submitting attributes not explicitly exposed by - the API. - promotion_status (google.shopping.merchant_promotions_v1beta.types.PromotionStatus): - Output only. The `status of a - promotion `__, - data validation issues, that is, information about a - promotion computed asynchronously. - version_number (int): - Optional. Represents the existing version (freshness) of the - promotion, which can be used to preserve the right order - when multiple updates are done at the same time. - - If set, the insertion is prevented when version number is - lower than the current version number of the existing - promotion. Re-insertion (for example, promotion refresh - after 30 days) can be performed with the current - ``version_number``. - - If the operation is prevented, the aborted exception will be - thrown. - - This field is a member of `oneof`_ ``_version_number``. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - promotion_id: str = proto.Field( - proto.STRING, - number=2, - ) - content_language: str = proto.Field( - proto.STRING, - number=3, - ) - target_country: str = proto.Field( - proto.STRING, - number=4, - ) - redemption_channel: MutableSequence[promotions_common.RedemptionChannel] = proto.RepeatedField( - proto.ENUM, - number=5, - enum=promotions_common.RedemptionChannel, - ) - data_source: str = proto.Field( - proto.STRING, - number=6, - ) - attributes: promotions_common.Attributes = proto.Field( - proto.MESSAGE, - number=7, - message=promotions_common.Attributes, - ) - custom_attributes: MutableSequence[types.CustomAttribute] = proto.RepeatedField( - proto.MESSAGE, - number=8, - message=types.CustomAttribute, - ) - promotion_status: promotions_common.PromotionStatus = proto.Field( - proto.MESSAGE, - number=9, - message=promotions_common.PromotionStatus, - ) - version_number: int = proto.Field( - proto.INT64, - number=10, - optional=True, - ) - - -class InsertPromotionRequest(proto.Message): - r"""Request message for the ``InsertPromotion`` method. - - Attributes: - parent (str): - Required. The account where the promotion - will be inserted. Format: accounts/{account} - promotion (google.shopping.merchant_promotions_v1beta.types.Promotion): - Required. The promotion to insert. - data_source (str): - Required. The data source of the - `promotion `__ - Format: ``accounts/{account}/dataSources/{datasource}``. - """ - - parent: str = proto.Field( - proto.STRING, - number=1, - ) - promotion: 'Promotion' = proto.Field( - proto.MESSAGE, - number=2, - message='Promotion', - ) - data_source: str = proto.Field( - proto.STRING, - number=3, - ) - - -class GetPromotionRequest(proto.Message): - r"""Request message for the ``GetPromotion`` method. - - Attributes: - name (str): - Required. The name of the promotion to retrieve. Format: - ``accounts/{account}/promotions/{promotions}`` - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - - -class ListPromotionsRequest(proto.Message): - r"""Request message for the ``ListPromotions`` method. - - Attributes: - parent (str): - Required. The account to list processed promotions for. - Format: ``accounts/{account}`` - page_size (int): - Output only. The maximum number of promotions - to return. The service may return fewer than - this value. The maximum value is 1000; values - above 1000 will be coerced to 1000. If - unspecified, the maximum number of promotions - will be returned. - page_token (str): - Output only. A page token, received from a previous - ``ListPromotions`` call. Provide this to retrieve the - subsequent page. - - When paginating, all other parameters provided to - ``ListPromotions`` must match the call that provided the - page token. - """ - - 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 ListPromotionsResponse(proto.Message): - r"""Response message for the ``ListPromotions`` method. - - Attributes: - promotions (MutableSequence[google.shopping.merchant_promotions_v1beta.types.Promotion]): - The processed promotions from the specified - account. - next_page_token (str): - A token, which can be sent as ``page_token`` to retrieve the - next page. If this field is omitted, there are no subsequent - pages. - """ - - @property - def raw_page(self): - return self - - promotions: MutableSequence['Promotion'] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message='Promotion', - ) - next_page_token: str = proto.Field( - proto.STRING, - number=2, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions_common.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions_common.py deleted file mode 100644 index 290e4bcf4ee5..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/google/shopping/merchant_promotions_v1beta/types/promotions_common.py +++ /dev/null @@ -1,671 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.shopping.type.types import types -from google.type import interval_pb2 # type: ignore - - -__protobuf__ = proto.module( - package='google.shopping.merchant.promotions.v1beta', - manifest={ - 'ProductApplicability', - 'StoreApplicability', - 'OfferType', - 'RedemptionChannel', - 'CouponValueType', - 'Attributes', - 'PromotionStatus', - }, -) - - -class ProductApplicability(proto.Enum): - r"""Which product or list of products the promotion applies to. - - Values: - PRODUCT_APPLICABILITY_UNSPECIFIED (0): - Which products the promotion applies to is - unknown. - ALL_PRODUCTS (1): - Applicable to all products. - SPECIFIC_PRODUCTS (2): - Applicable to only a single product or list - of products. - """ - PRODUCT_APPLICABILITY_UNSPECIFIED = 0 - ALL_PRODUCTS = 1 - SPECIFIC_PRODUCTS = 2 - - -class StoreApplicability(proto.Enum): - r"""Store codes or list of store codes the promotion applies to. - Only for Local inventory ads promotions. - - Values: - STORE_APPLICABILITY_UNSPECIFIED (0): - Which store codes the promotion applies to is - unknown. - ALL_STORES (1): - Promotion applies to all stores. - SPECIFIC_STORES (2): - Promotion applies to only the specified - stores. - """ - STORE_APPLICABILITY_UNSPECIFIED = 0 - ALL_STORES = 1 - SPECIFIC_STORES = 2 - - -class OfferType(proto.Enum): - r"""Offer type of a promotion. - - Values: - OFFER_TYPE_UNSPECIFIED (0): - Unknown offer type. - NO_CODE (1): - Offer type without a code. - GENERIC_CODE (2): - Offer type with a code. Generic redemption code for the - promotion is required when ``offerType`` = ``GENERIC_CODE``. - """ - OFFER_TYPE_UNSPECIFIED = 0 - NO_CODE = 1 - GENERIC_CODE = 2 - - -class RedemptionChannel(proto.Enum): - r"""Channel of a promotion. - - Values: - REDEMPTION_CHANNEL_UNSPECIFIED (0): - Indicates that the channel is unspecified. - IN_STORE (1): - Indicates that the channel is in store. This is same as - ``local`` channel used for ``products``. - ONLINE (2): - Indicates that the channel is online. - """ - REDEMPTION_CHANNEL_UNSPECIFIED = 0 - IN_STORE = 1 - ONLINE = 2 - - -class CouponValueType(proto.Enum): - r"""`Coupon value - type `__ - of a promotion. - - Values: - COUPON_VALUE_TYPE_UNSPECIFIED (0): - Indicates that the coupon value type is - unspecified. - MONEY_OFF (1): - Money off coupon value type. - PERCENT_OFF (2): - Percent off coupon value type. - BUY_M_GET_N_MONEY_OFF (3): - Buy M quantity, get N money off coupon value type. - ``minimum_purchase_quantity`` and - ``get_this_quantity_discounted`` must be present. - ``money_off_amount`` must also be present. - BUY_M_GET_N_PERCENT_OFF (4): - Buy M quantity, get N percent off coupon value type. - ``minimum_purchase_quantity`` and - ``get_this_quantity_discounted`` must be present. - ``percent_off_percentage`` must also be present. - BUY_M_GET_MONEY_OFF (5): - Buy M quantity, get money off. ``minimum_purchase_quantity`` - and ``money_off_amount`` must be present. - BUY_M_GET_PERCENT_OFF (6): - Buy M quantity, get money off. ``minimum_purchase_quantity`` - and ``percent_off_percentage`` must be present. - FREE_GIFT (7): - Free gift with description only. - FREE_GIFT_WITH_VALUE (8): - Free gift with monetary value. - FREE_GIFT_WITH_ITEM_ID (9): - Free gift with item ID. - FREE_SHIPPING_STANDARD (10): - Standard free shipping coupon value type. - FREE_SHIPPING_OVERNIGHT (11): - Overnight free shipping coupon value type. - FREE_SHIPPING_TWO_DAY (12): - Two day free shipping coupon value type. - """ - COUPON_VALUE_TYPE_UNSPECIFIED = 0 - MONEY_OFF = 1 - PERCENT_OFF = 2 - BUY_M_GET_N_MONEY_OFF = 3 - BUY_M_GET_N_PERCENT_OFF = 4 - BUY_M_GET_MONEY_OFF = 5 - BUY_M_GET_PERCENT_OFF = 6 - FREE_GIFT = 7 - FREE_GIFT_WITH_VALUE = 8 - FREE_GIFT_WITH_ITEM_ID = 9 - FREE_SHIPPING_STANDARD = 10 - FREE_SHIPPING_OVERNIGHT = 11 - FREE_SHIPPING_TWO_DAY = 12 - - -class Attributes(proto.Message): - r"""Attributes. - - Attributes: - product_applicability (google.shopping.merchant_promotions_v1beta.types.ProductApplicability): - Required. Applicability of the promotion to either all - products or `only specific - products `__. - offer_type (google.shopping.merchant_promotions_v1beta.types.OfferType): - Required. - `Type `__ - of the promotion. Use this attribute to indicate whether or - not customers need a coupon code to redeem your promotion. - generic_redemption_code (str): - Optional. Generic redemption code for the promotion. To be - used with the ``offerType`` field and must meet the `minimum - requirements `__. - long_title (str): - Required. `Long - title `__ - for the promotion. - coupon_value_type (google.shopping.merchant_promotions_v1beta.types.CouponValueType): - Required. The [coupon value type] - (https://support.google.com/merchants/answer/13861986?ref_topic=13773355&sjid=17642868584668136159-NC) - attribute to signal the type of promotion that you are - running. Depending on type of the selected coupon value - `some attributes are - required `__. - promotion_destinations (MutableSequence[google.shopping.type.types.Destination.DestinationEnum]): - Required. The list of destinations where the promotion - applies to. If you don't specify a destination by including - a supported value in your data source, your promotion will - display in Shopping ads and free listings by default. - - You may have previously submitted the following values as - destinations for your products: Shopping Actions, Surfaces - across Google, Local surfaces across Google. To represent - these values use ``FREE_LISTINGS``, ``FREE_LOCAL_LISTINGS``, - ``LOCAL_INVENTORY_ADS``. For more details see `Promotion - destination `__ - item_id_inclusion (MutableSequence[str]): - Optional. Product filter by `item - ID `__ - for the promotion. The product filter attributes only - applies when the products eligible for promotion product - applicability ``product_applicability`` attribute is set to - `specific_products `__. - brand_inclusion (MutableSequence[str]): - Optional. Product filter by brand for the promotion. The - product filter attributes only applies when the products - eligible for promotion product applicability - ``product_applicability`` attribute is set to - `specific_products `__. - item_group_id_inclusion (MutableSequence[str]): - Optional. Product filter by item group ID for the promotion. - The product filter attributes only applies when the products - eligible for promotion product applicability - [product_applicability] attribute is set to - `specific_products `__. - product_type_inclusion (MutableSequence[str]): - Optional. Product filter by product type for the promotion. - The product filter attributes only applies when the products - eligible for promotion product applicability - ``product_applicability`` attribute is set to - `specific_products `__. - item_id_exclusion (MutableSequence[str]): - Optional. Product filter by `item ID - exclusion `__ - for the promotion. The product filter attributes only - applies when the products eligible for promotion product - applicability ``product_applicability`` attribute is set to - `specific_products `__. - brand_exclusion (MutableSequence[str]): - Optional. Product filter by `brand - exclusion `__ - for the promotion. The product filter attributes only - applies when the products eligible for promotion product - applicability ``product_applicability`` attribute is set to - `specific_products `__. - item_group_id_exclusion (MutableSequence[str]): - Optional. Product filter by `item group - ID `__. - The product filter attributes only applies when the products - eligible for promotion product applicability - ``product_applicability`` attribute is set to - `specific_products `__. - exclusion for the promotion. - product_type_exclusion (MutableSequence[str]): - Optional. Product filter by `product type - exclusion `__ - for the promotion. The product filter attributes only - applies when the products eligible for promotion product - applicability ``product_applicability`` attribute is set to - `specific_products `__. - minimum_purchase_amount (google.shopping.type.types.Price): - Optional. `Minimum purchase - amount `__ - for the promotion. - minimum_purchase_quantity (int): - Optional. `Minimum purchase - quantity `__ - for the promotion. - limit_quantity (int): - Optional. `Maximum purchase - quantity `__ - for the promotion. - limit_value (google.shopping.type.types.Price): - Optional. `Maximum product - price `__ - for promotion. - percent_off (int): - Optional. The `percentage - discount `__ - offered in the promotion. - money_off_amount (google.shopping.type.types.Price): - Optional. The `money off - amount `__ - offered in the promotion. - get_this_quantity_discounted (int): - Optional. The number of items discounted in the promotion. - The attribute is set when ``couponValueType`` is equal to - ``buy_m_get_n_money_off`` or ``buy_m_get_n_percent_off``. - free_gift_value (google.shopping.type.types.Price): - Optional. `Free gift - value `__ - for the promotion. - free_gift_description (str): - Optional. `Free gift - description `__ - for the promotion. - free_gift_item_id (str): - Optional. `Free gift item - ID `__ - for the promotion. - promotion_effective_time_period (google.type.interval_pb2.Interval): - Required. ``TimePeriod`` representation of the promotion's - effective dates. This attribute specifies that the promotion - can be tested on your online store during this time period. - promotion_display_time_period (google.type.interval_pb2.Interval): - Optional. ``TimePeriod`` representation of the promotion's - display dates. This attribute specifies the date and time - frame when the promotion will be live on Google.com and - Shopping ads. If the display time period for promotion - ``promotion_display_time_period`` attribute is not - specified, the promotion effective time period - ``promotion_effective_time_period`` determines the date and - time frame when the promotion will be live on Google.com and - Shopping ads. - store_applicability (google.shopping.merchant_promotions_v1beta.types.StoreApplicability): - Optional. Whether the promotion applies to `all stores, or - only specified - stores `__. - Local Inventory ads promotions throw an error if no store - applicability is included. An ``INVALID_ARGUMENT`` error is - thrown if ``store_applicability`` is set to ``ALL_STORES`` - and ``store_codes_inclusion`` or ``score_code_exclusion`` is - set to a value. - store_codes_inclusion (MutableSequence[str]): - Optional. `Store codes to - include `__ - for the promotion. The store filter attributes only applies - when the ``store_applicability`` attribute is set to - `specific_stores `__. - - Store code (the store ID from your Business Profile) of the - physical store the product is sold in. See the `Local - product inventory data - specification `__ - for more information. - store_codes_exclusion (MutableSequence[str]): - Optional. `Store codes to - exclude `__ - for the promotion. The store filter attributes only applies - when the ``store_applicability`` attribute is set to - `specific_stores `__. - promotion_url (str): - Optional. URL to the page on the merchant's site where the - promotion shows. Local Inventory ads promotions throw an - error if no ``promotion_url`` is included. URL is used to - confirm that the promotion is valid and can be redeemed. - """ - - product_applicability: 'ProductApplicability' = proto.Field( - proto.ENUM, - number=1, - enum='ProductApplicability', - ) - offer_type: 'OfferType' = proto.Field( - proto.ENUM, - number=2, - enum='OfferType', - ) - generic_redemption_code: str = proto.Field( - proto.STRING, - number=3, - ) - long_title: str = proto.Field( - proto.STRING, - number=4, - ) - coupon_value_type: 'CouponValueType' = proto.Field( - proto.ENUM, - number=5, - enum='CouponValueType', - ) - promotion_destinations: MutableSequence[types.Destination.DestinationEnum] = proto.RepeatedField( - proto.ENUM, - number=6, - enum=types.Destination.DestinationEnum, - ) - item_id_inclusion: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=7, - ) - brand_inclusion: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=8, - ) - item_group_id_inclusion: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=9, - ) - product_type_inclusion: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=10, - ) - item_id_exclusion: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=11, - ) - brand_exclusion: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=12, - ) - item_group_id_exclusion: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=13, - ) - product_type_exclusion: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=14, - ) - minimum_purchase_amount: types.Price = proto.Field( - proto.MESSAGE, - number=15, - message=types.Price, - ) - minimum_purchase_quantity: int = proto.Field( - proto.INT64, - number=16, - ) - limit_quantity: int = proto.Field( - proto.INT64, - number=17, - ) - limit_value: types.Price = proto.Field( - proto.MESSAGE, - number=18, - message=types.Price, - ) - percent_off: int = proto.Field( - proto.INT64, - number=19, - ) - money_off_amount: types.Price = proto.Field( - proto.MESSAGE, - number=20, - message=types.Price, - ) - get_this_quantity_discounted: int = proto.Field( - proto.INT64, - number=21, - ) - free_gift_value: types.Price = proto.Field( - proto.MESSAGE, - number=22, - message=types.Price, - ) - free_gift_description: str = proto.Field( - proto.STRING, - number=23, - ) - free_gift_item_id: str = proto.Field( - proto.STRING, - number=24, - ) - promotion_effective_time_period: interval_pb2.Interval = proto.Field( - proto.MESSAGE, - number=25, - message=interval_pb2.Interval, - ) - promotion_display_time_period: interval_pb2.Interval = proto.Field( - proto.MESSAGE, - number=26, - message=interval_pb2.Interval, - ) - store_applicability: 'StoreApplicability' = proto.Field( - proto.ENUM, - number=28, - enum='StoreApplicability', - ) - store_codes_inclusion: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=29, - ) - store_codes_exclusion: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=30, - ) - promotion_url: str = proto.Field( - proto.STRING, - number=31, - ) - - -class PromotionStatus(proto.Message): - r"""The status of the promotion. - - Attributes: - destination_statuses (MutableSequence[google.shopping.merchant_promotions_v1beta.types.PromotionStatus.DestinationStatus]): - Output only. The intended destinations for - the promotion. - item_level_issues (MutableSequence[google.shopping.merchant_promotions_v1beta.types.PromotionStatus.ItemLevelIssue]): - Output only. A list of issues associated with - the promotion. - creation_date (google.protobuf.timestamp_pb2.Timestamp): - Output only. Date on which the promotion has been created in - `ISO 8601 `__ format: - Date, time, and offset, for example - ``2020-01-02T09:00:00+01:00`` or ``2020-01-02T09:00:00Z`` - last_update_date (google.protobuf.timestamp_pb2.Timestamp): - Output only. Date on which the promotion status has been - last updated in `ISO - 8601 `__ format: - Date, time, and offset, for example - ``2020-01-02T09:00:00+01:00`` or ``2020-01-02T09:00:00Z`` - """ - - class DestinationStatus(proto.Message): - r"""The status for the specified destination. - - Attributes: - reporting_context (google.shopping.type.types.ReportingContext.ReportingContextEnum): - Output only. The name of the promotion - destination. - status (google.shopping.merchant_promotions_v1beta.types.PromotionStatus.DestinationStatus.State): - Output only. The status for the specified - destination. - """ - class State(proto.Enum): - r"""The current state of the promotion. - - Values: - STATE_UNSPECIFIED (0): - Unknown promotion state. - IN_REVIEW (1): - The promotion is under review. - REJECTED (2): - The promotion is disapproved. - LIVE (3): - The promotion is approved and active. - STOPPED (4): - The promotion is stopped by merchant. - EXPIRED (5): - The promotion is no longer active. - PENDING (6): - The promotion is not stopped, and all reviews - are approved, but the active date is in the - future. - """ - STATE_UNSPECIFIED = 0 - IN_REVIEW = 1 - REJECTED = 2 - LIVE = 3 - STOPPED = 4 - EXPIRED = 5 - PENDING = 6 - - reporting_context: types.ReportingContext.ReportingContextEnum = proto.Field( - proto.ENUM, - number=1, - enum=types.ReportingContext.ReportingContextEnum, - ) - status: 'PromotionStatus.DestinationStatus.State' = proto.Field( - proto.ENUM, - number=2, - enum='PromotionStatus.DestinationStatus.State', - ) - - class ItemLevelIssue(proto.Message): - r"""The issue associated with the promotion. - - Attributes: - code (str): - Output only. The error code of the issue. - severity (google.shopping.merchant_promotions_v1beta.types.PromotionStatus.ItemLevelIssue.Severity): - Output only. How this issue affects serving - of the promotion. - resolution (str): - Output only. Whether the issue can be - resolved by the merchant. - attribute (str): - Output only. The attribute's name, if the - issue is caused by a single attribute. - reporting_context (google.shopping.type.types.ReportingContext.ReportingContextEnum): - Output only. The destination the issue - applies to. - description (str): - Output only. A short issue description in - English. - detail (str): - Output only. A detailed issue description in - English. - documentation (str): - Output only. The URL of a web page to help - with resolving this issue. - applicable_countries (MutableSequence[str]): - Output only. List of country codes (ISO - 3166-1 alpha-2) where issue applies to the - offer. - """ - class Severity(proto.Enum): - r"""The severity of the issue. - - Values: - SEVERITY_UNSPECIFIED (0): - Not specified. - NOT_IMPACTED (1): - This issue represents a warning and does not - have a direct affect on the promotion. - DEMOTED (2): - The promotion is demoted and most likely have - limited performance in search results - DISAPPROVED (3): - Issue disapproves the promotion. - """ - SEVERITY_UNSPECIFIED = 0 - NOT_IMPACTED = 1 - DEMOTED = 2 - DISAPPROVED = 3 - - code: str = proto.Field( - proto.STRING, - number=1, - ) - severity: 'PromotionStatus.ItemLevelIssue.Severity' = proto.Field( - proto.ENUM, - number=2, - enum='PromotionStatus.ItemLevelIssue.Severity', - ) - resolution: str = proto.Field( - proto.STRING, - number=3, - ) - attribute: str = proto.Field( - proto.STRING, - number=4, - ) - reporting_context: types.ReportingContext.ReportingContextEnum = proto.Field( - proto.ENUM, - number=5, - enum=types.ReportingContext.ReportingContextEnum, - ) - description: str = proto.Field( - proto.STRING, - number=6, - ) - detail: str = proto.Field( - proto.STRING, - number=7, - ) - documentation: str = proto.Field( - proto.STRING, - number=8, - ) - applicable_countries: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=9, - ) - - destination_statuses: MutableSequence[DestinationStatus] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=DestinationStatus, - ) - item_level_issues: MutableSequence[ItemLevelIssue] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message=ItemLevelIssue, - ) - creation_date: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=3, - message=timestamp_pb2.Timestamp, - ) - last_update_date: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=4, - message=timestamp_pb2.Timestamp, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/mypy.ini b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/mypy.ini deleted file mode 100644 index 574c5aed394b..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/mypy.ini +++ /dev/null @@ -1,3 +0,0 @@ -[mypy] -python_version = 3.7 -namespace_packages = True diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/noxfile.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/noxfile.py deleted file mode 100644 index 3cd901f36b88..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/noxfile.py +++ /dev/null @@ -1,280 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 re -import shutil -import subprocess -import sys - - -import nox # type: ignore - -ALL_PYTHON = [ - "3.7", - "3.8", - "3.9", - "3.10", - "3.11", - "3.12", - "3.13", -] - -CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() - -LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" -PACKAGE_NAME = 'google-shopping-merchant-promotions' - -BLACK_VERSION = "black==22.3.0" -BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] -DEFAULT_PYTHON_VERSION = "3.13" - -nox.sessions = [ - "unit", - "cover", - "mypy", - "check_lower_bounds" - # exclude update_lower_bounds from default - "docs", - "blacken", - "lint", - "prerelease_deps", -] - -@nox.session(python=ALL_PYTHON) -@nox.parametrize( - "protobuf_implementation", - [ "python", "upb", "cpp" ], -) -def unit(session, protobuf_implementation): - """Run the unit test suite.""" - - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): - session.skip("cpp implementation is not supported in python 3.11+") - - session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') - session.install('-e', '.', "-c", f"testing/constraints-{session.python}.txt") - - # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. - # The 'cpp' implementation requires Protobuf<4. - if protobuf_implementation == "cpp": - session.install("protobuf<4") - - session.run( - 'py.test', - '--quiet', - '--cov=google/shopping/merchant_promotions_v1beta/', - '--cov=tests/', - '--cov-config=.coveragerc', - '--cov-report=term', - '--cov-report=html', - os.path.join('tests', 'unit', ''.join(session.posargs)), - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - -@nox.session(python=ALL_PYTHON[-1]) -@nox.parametrize( - "protobuf_implementation", - [ "python", "upb", "cpp" ], -) -def prerelease_deps(session, protobuf_implementation): - """Run the unit test suite against pre-release versions of dependencies.""" - - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): - session.skip("cpp implementation is not supported in python 3.11+") - - # Install test environment dependencies - session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') - - # Install the package without dependencies - session.install('-e', '.', '--no-deps') - - # We test the minimum dependency versions using the minimum Python - # version so the lowest python runtime that we test has a corresponding constraints - # file, located at `testing/constraints--.txt`, which contains all of the - # dependencies and extras. - with open( - CURRENT_DIRECTORY - / "testing" - / f"constraints-{ALL_PYTHON[0]}.txt", - encoding="utf-8", - ) as constraints_file: - constraints_text = constraints_file.read() - - # Ignore leading whitespace and comment lines. - constraints_deps = [ - match.group(1) - for match in re.finditer( - r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE - ) - ] - - session.install(*constraints_deps) - - prerel_deps = [ - "googleapis-common-protos", - "google-api-core", - "google-auth", - # Exclude grpcio!=1.67.0rc1 which does not support python 3.13 - "grpcio!=1.67.0rc1", - "grpcio-status", - "protobuf", - "proto-plus", - ] - - for dep in prerel_deps: - session.install("--pre", "--no-deps", "--upgrade", dep) - - # Remaining dependencies - other_deps = [ - "requests", - ] - session.install(*other_deps) - - # Print out prerelease package versions - - session.run("python", "-c", "import google.api_core; print(google.api_core.__version__)") - session.run("python", "-c", "import google.auth; print(google.auth.__version__)") - session.run("python", "-c", "import grpc; print(grpc.__version__)") - session.run( - "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" - ) - session.run( - "python", "-c", "import proto; print(proto.__version__)" - ) - - session.run( - 'py.test', - '--quiet', - '--cov=google/shopping/merchant_promotions_v1beta/', - '--cov=tests/', - '--cov-config=.coveragerc', - '--cov-report=term', - '--cov-report=html', - os.path.join('tests', 'unit', ''.join(session.posargs)), - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - - -@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', - '-p', - '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, - ) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_async.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_async.py deleted file mode 100644 index 66bd0db4ca0d..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_async.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for GetPromotion -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-shopping-merchant-promotions - - -# [START merchantapi_v1beta_generated_PromotionsService_GetPromotion_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.shopping import merchant_promotions_v1beta - - -async def sample_get_promotion(): - # Create a client - client = merchant_promotions_v1beta.PromotionsServiceAsyncClient() - - # Initialize request argument(s) - request = merchant_promotions_v1beta.GetPromotionRequest( - name="name_value", - ) - - # Make the request - response = await client.get_promotion(request=request) - - # Handle the response - print(response) - -# [END merchantapi_v1beta_generated_PromotionsService_GetPromotion_async] diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_sync.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_sync.py deleted file mode 100644 index 6b8e9dade3e9..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_get_promotion_sync.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for GetPromotion -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-shopping-merchant-promotions - - -# [START merchantapi_v1beta_generated_PromotionsService_GetPromotion_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.shopping import merchant_promotions_v1beta - - -def sample_get_promotion(): - # Create a client - client = merchant_promotions_v1beta.PromotionsServiceClient() - - # Initialize request argument(s) - request = merchant_promotions_v1beta.GetPromotionRequest( - name="name_value", - ) - - # Make the request - response = client.get_promotion(request=request) - - # Handle the response - print(response) - -# [END merchantapi_v1beta_generated_PromotionsService_GetPromotion_sync] diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_async.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_async.py deleted file mode 100644 index d9245ecabde7..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_async.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for InsertPromotion -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-shopping-merchant-promotions - - -# [START merchantapi_v1beta_generated_PromotionsService_InsertPromotion_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.shopping import merchant_promotions_v1beta - - -async def sample_insert_promotion(): - # Create a client - client = merchant_promotions_v1beta.PromotionsServiceAsyncClient() - - # Initialize request argument(s) - promotion = merchant_promotions_v1beta.Promotion() - promotion.promotion_id = "promotion_id_value" - promotion.content_language = "content_language_value" - promotion.target_country = "target_country_value" - promotion.redemption_channel = ['ONLINE'] - - request = merchant_promotions_v1beta.InsertPromotionRequest( - parent="parent_value", - promotion=promotion, - data_source="data_source_value", - ) - - # Make the request - response = await client.insert_promotion(request=request) - - # Handle the response - print(response) - -# [END merchantapi_v1beta_generated_PromotionsService_InsertPromotion_async] diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_sync.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_sync.py deleted file mode 100644 index 2fd44913b58c..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_insert_promotion_sync.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for InsertPromotion -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-shopping-merchant-promotions - - -# [START merchantapi_v1beta_generated_PromotionsService_InsertPromotion_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.shopping import merchant_promotions_v1beta - - -def sample_insert_promotion(): - # Create a client - client = merchant_promotions_v1beta.PromotionsServiceClient() - - # Initialize request argument(s) - promotion = merchant_promotions_v1beta.Promotion() - promotion.promotion_id = "promotion_id_value" - promotion.content_language = "content_language_value" - promotion.target_country = "target_country_value" - promotion.redemption_channel = ['ONLINE'] - - request = merchant_promotions_v1beta.InsertPromotionRequest( - parent="parent_value", - promotion=promotion, - data_source="data_source_value", - ) - - # Make the request - response = client.insert_promotion(request=request) - - # Handle the response - print(response) - -# [END merchantapi_v1beta_generated_PromotionsService_InsertPromotion_sync] diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_async.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_async.py deleted file mode 100644 index ae88a1355d74..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_async.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListPromotions -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-shopping-merchant-promotions - - -# [START merchantapi_v1beta_generated_PromotionsService_ListPromotions_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.shopping import merchant_promotions_v1beta - - -async def sample_list_promotions(): - # Create a client - client = merchant_promotions_v1beta.PromotionsServiceAsyncClient() - - # Initialize request argument(s) - request = merchant_promotions_v1beta.ListPromotionsRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_promotions(request=request) - - # Handle the response - async for response in page_result: - print(response) - -# [END merchantapi_v1beta_generated_PromotionsService_ListPromotions_async] diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_sync.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_sync.py deleted file mode 100644 index d2d3f2a247df..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/merchantapi_v1beta_generated_promotions_service_list_promotions_sync.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListPromotions -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-shopping-merchant-promotions - - -# [START merchantapi_v1beta_generated_PromotionsService_ListPromotions_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.shopping import merchant_promotions_v1beta - - -def sample_list_promotions(): - # Create a client - client = merchant_promotions_v1beta.PromotionsServiceClient() - - # Initialize request argument(s) - request = merchant_promotions_v1beta.ListPromotionsRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_promotions(request=request) - - # Handle the response - for response in page_result: - print(response) - -# [END merchantapi_v1beta_generated_PromotionsService_ListPromotions_sync] diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1beta.json b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1beta.json deleted file mode 100644 index 4b7f108a5403..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.promotions.v1beta.json +++ /dev/null @@ -1,490 +0,0 @@ -{ - "clientLibrary": { - "apis": [ - { - "id": "google.shopping.merchant.promotions.v1beta", - "version": "v1beta" - } - ], - "language": "PYTHON", - "name": "google-shopping-merchant-promotions", - "version": "0.1.0" - }, - "snippets": [ - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceAsyncClient", - "shortName": "PromotionsServiceAsyncClient" - }, - "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceAsyncClient.get_promotion", - "method": { - "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService.GetPromotion", - "service": { - "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService", - "shortName": "PromotionsService" - }, - "shortName": "GetPromotion" - }, - "parameters": [ - { - "name": "request", - "type": "google.shopping.merchant_promotions_v1beta.types.GetPromotionRequest" - }, - { - "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.shopping.merchant_promotions_v1beta.types.Promotion", - "shortName": "get_promotion" - }, - "description": "Sample for GetPromotion", - "file": "merchantapi_v1beta_generated_promotions_service_get_promotion_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "merchantapi_v1beta_generated_PromotionsService_GetPromotion_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": "merchantapi_v1beta_generated_promotions_service_get_promotion_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceClient", - "shortName": "PromotionsServiceClient" - }, - "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceClient.get_promotion", - "method": { - "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService.GetPromotion", - "service": { - "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService", - "shortName": "PromotionsService" - }, - "shortName": "GetPromotion" - }, - "parameters": [ - { - "name": "request", - "type": "google.shopping.merchant_promotions_v1beta.types.GetPromotionRequest" - }, - { - "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.shopping.merchant_promotions_v1beta.types.Promotion", - "shortName": "get_promotion" - }, - "description": "Sample for GetPromotion", - "file": "merchantapi_v1beta_generated_promotions_service_get_promotion_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "merchantapi_v1beta_generated_PromotionsService_GetPromotion_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": "merchantapi_v1beta_generated_promotions_service_get_promotion_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceAsyncClient", - "shortName": "PromotionsServiceAsyncClient" - }, - "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceAsyncClient.insert_promotion", - "method": { - "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService.InsertPromotion", - "service": { - "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService", - "shortName": "PromotionsService" - }, - "shortName": "InsertPromotion" - }, - "parameters": [ - { - "name": "request", - "type": "google.shopping.merchant_promotions_v1beta.types.InsertPromotionRequest" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.shopping.merchant_promotions_v1beta.types.Promotion", - "shortName": "insert_promotion" - }, - "description": "Sample for InsertPromotion", - "file": "merchantapi_v1beta_generated_promotions_service_insert_promotion_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "merchantapi_v1beta_generated_PromotionsService_InsertPromotion_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": "merchantapi_v1beta_generated_promotions_service_insert_promotion_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceClient", - "shortName": "PromotionsServiceClient" - }, - "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceClient.insert_promotion", - "method": { - "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService.InsertPromotion", - "service": { - "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService", - "shortName": "PromotionsService" - }, - "shortName": "InsertPromotion" - }, - "parameters": [ - { - "name": "request", - "type": "google.shopping.merchant_promotions_v1beta.types.InsertPromotionRequest" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.shopping.merchant_promotions_v1beta.types.Promotion", - "shortName": "insert_promotion" - }, - "description": "Sample for InsertPromotion", - "file": "merchantapi_v1beta_generated_promotions_service_insert_promotion_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "merchantapi_v1beta_generated_PromotionsService_InsertPromotion_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": "merchantapi_v1beta_generated_promotions_service_insert_promotion_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceAsyncClient", - "shortName": "PromotionsServiceAsyncClient" - }, - "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceAsyncClient.list_promotions", - "method": { - "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService.ListPromotions", - "service": { - "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService", - "shortName": "PromotionsService" - }, - "shortName": "ListPromotions" - }, - "parameters": [ - { - "name": "request", - "type": "google.shopping.merchant_promotions_v1beta.types.ListPromotionsRequest" - }, - { - "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.shopping.merchant_promotions_v1beta.services.promotions_service.pagers.ListPromotionsAsyncPager", - "shortName": "list_promotions" - }, - "description": "Sample for ListPromotions", - "file": "merchantapi_v1beta_generated_promotions_service_list_promotions_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "merchantapi_v1beta_generated_PromotionsService_ListPromotions_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": "merchantapi_v1beta_generated_promotions_service_list_promotions_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceClient", - "shortName": "PromotionsServiceClient" - }, - "fullName": "google.shopping.merchant_promotions_v1beta.PromotionsServiceClient.list_promotions", - "method": { - "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService.ListPromotions", - "service": { - "fullName": "google.shopping.merchant.promotions.v1beta.PromotionsService", - "shortName": "PromotionsService" - }, - "shortName": "ListPromotions" - }, - "parameters": [ - { - "name": "request", - "type": "google.shopping.merchant_promotions_v1beta.types.ListPromotionsRequest" - }, - { - "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.shopping.merchant_promotions_v1beta.services.promotions_service.pagers.ListPromotionsPager", - "shortName": "list_promotions" - }, - "description": "Sample for ListPromotions", - "file": "merchantapi_v1beta_generated_promotions_service_list_promotions_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "merchantapi_v1beta_generated_PromotionsService_ListPromotions_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": "merchantapi_v1beta_generated_promotions_service_list_promotions_sync.py" - } - ] -} diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/scripts/fixup_merchant_promotions_v1beta_keywords.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/scripts/fixup_merchant_promotions_v1beta_keywords.py deleted file mode 100644 index 398615e0afb5..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/scripts/fixup_merchant_promotions_v1beta_keywords.py +++ /dev/null @@ -1,178 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 merchant_promotionsCallTransformer(cst.CSTTransformer): - CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') - METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { - 'get_promotion': ('name', ), - 'insert_promotion': ('parent', 'promotion', 'data_source', ), - 'list_promotions': ('parent', 'page_size', 'page_token', ), - } - - 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=merchant_promotionsCallTransformer(), -): - """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 merchant_promotions 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/google-shopping-merchant-promotions/v1beta/setup.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/setup.py deleted file mode 100644 index a4ef40e7ce4a..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/setup.py +++ /dev/null @@ -1,99 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 re - -import setuptools # type: ignore - -package_root = os.path.abspath(os.path.dirname(__file__)) - -name = 'google-shopping-merchant-promotions' - - -description = "Google Shopping Merchant Promotions API client library" - -version = None - -with open(os.path.join(package_root, 'google/shopping/merchant_promotions/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) - assert (len(version_candidates) == 1) - version = version_candidates[0] - -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.1, <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.*", - # Exclude incompatible versions of `google-auth` - # See https://github.com/googleapis/google-cloud-python/issues/12364 - "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", - "proto-plus >= 1.22.3, <2.0.0dev", - "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", - "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", - "google-shopping-type >= 0.1.6, <1.0.0dev", -] -extras = { -} -url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-promotions" - -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.find_namespace_packages() - if package.startswith("google") -] - -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", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Operating System :: OS Independent", - "Topic :: Internet", - ], - platforms="Posix; MacOS X; Windows", - packages=packages, - python_requires=">=3.7", - install_requires=dependencies, - extras_require=extras, - include_package_data=True, - zip_safe=False, -) diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.10.txt b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.10.txt deleted file mode 100644 index 4cae520d02b2..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.10.txt +++ /dev/null @@ -1,7 +0,0 @@ -# -*- 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 -google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.11.txt b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.11.txt deleted file mode 100644 index 4cae520d02b2..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.11.txt +++ /dev/null @@ -1,7 +0,0 @@ -# -*- 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 -google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.12.txt b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.12.txt deleted file mode 100644 index 4cae520d02b2..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.12.txt +++ /dev/null @@ -1,7 +0,0 @@ -# -*- 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 -google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.7.txt b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.7.txt deleted file mode 100644 index 130a0c0f80ab..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.7.txt +++ /dev/null @@ -1,11 +0,0 @@ -# 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.1 -google-auth==2.14.1 -proto-plus==1.22.3 -protobuf==3.20.2 -google-shopping-type==0.1.6 diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.8.txt b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.8.txt deleted file mode 100644 index 4cae520d02b2..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.8.txt +++ /dev/null @@ -1,7 +0,0 @@ -# -*- 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 -google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.9.txt b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.9.txt deleted file mode 100644 index 4cae520d02b2..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.9.txt +++ /dev/null @@ -1,7 +0,0 @@ -# -*- 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 -google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-promotions/v1beta/tests/unit/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/__init__.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py b/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py deleted file mode 100644 index 0d1f98a800e1..000000000000 --- a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/tests/unit/gapic/merchant_promotions_v1beta/test_promotions_service.py +++ /dev/null @@ -1,3661 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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, AsyncIterable -from google.protobuf import json_format -import json -import math -import pytest -from google.api_core import api_core_version -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 - -try: - from google.auth.aio import credentials as ga_credentials_async - HAS_GOOGLE_AUTH_AIO = True -except ImportError: # pragma: NO COVER - HAS_GOOGLE_AUTH_AIO = False - -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.api_core import retry as retries -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account -from google.protobuf import timestamp_pb2 # type: ignore -from google.shopping.merchant_promotions_v1beta.services.promotions_service import PromotionsServiceAsyncClient -from google.shopping.merchant_promotions_v1beta.services.promotions_service import PromotionsServiceClient -from google.shopping.merchant_promotions_v1beta.services.promotions_service import pagers -from google.shopping.merchant_promotions_v1beta.services.promotions_service import transports -from google.shopping.merchant_promotions_v1beta.types import promotions -from google.shopping.merchant_promotions_v1beta.types import promotions_common -from google.shopping.type.types import types -from google.type import interval_pb2 # type: ignore -import google.auth - - -async def mock_async_gen(data, chunk_size=1): - for i in range(0, len(data)): # pragma: NO COVER - chunk = data[i : i + chunk_size] - yield chunk.encode("utf-8") - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - -# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. -# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. -def async_anonymous_credentials(): - if HAS_GOOGLE_AUTH_AIO: - return ga_credentials_async.AnonymousCredentials() - return ga_credentials.AnonymousCredentials() - -# 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 - -# If default endpoint template is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint template so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint_template(client): - return "test.{UNIVERSE_DOMAIN}" if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) else client._DEFAULT_ENDPOINT_TEMPLATE - - -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 PromotionsServiceClient._get_default_mtls_endpoint(None) is None - assert PromotionsServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint - assert PromotionsServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint - assert PromotionsServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint - assert PromotionsServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint - assert PromotionsServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - -def test__read_environment_variables(): - assert PromotionsServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert PromotionsServiceClient._read_environment_variables() == (True, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - assert PromotionsServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError) as excinfo: - PromotionsServiceClient._read_environment_variables() - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - assert PromotionsServiceClient._read_environment_variables() == (False, "never", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - assert PromotionsServiceClient._read_environment_variables() == (False, "always", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): - assert PromotionsServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - PromotionsServiceClient._read_environment_variables() - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): - assert PromotionsServiceClient._read_environment_variables() == (False, "auto", "foo.com") - -def test__get_client_cert_source(): - mock_provided_cert_source = mock.Mock() - mock_default_cert_source = mock.Mock() - - assert PromotionsServiceClient._get_client_cert_source(None, False) is None - assert PromotionsServiceClient._get_client_cert_source(mock_provided_cert_source, False) is None - assert PromotionsServiceClient._get_client_cert_source(mock_provided_cert_source, True) == mock_provided_cert_source - - 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_default_cert_source): - assert PromotionsServiceClient._get_client_cert_source(None, True) is mock_default_cert_source - assert PromotionsServiceClient._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source - -@mock.patch.object(PromotionsServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceClient)) -@mock.patch.object(PromotionsServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceAsyncClient)) -def test__get_api_endpoint(): - api_override = "foo.com" - mock_client_cert_source = mock.Mock() - default_universe = PromotionsServiceClient._DEFAULT_UNIVERSE - default_endpoint = PromotionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) - mock_universe = "bar.com" - mock_endpoint = PromotionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) - - assert PromotionsServiceClient._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override - assert PromotionsServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == PromotionsServiceClient.DEFAULT_MTLS_ENDPOINT - assert PromotionsServiceClient._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint - assert PromotionsServiceClient._get_api_endpoint(None, None, default_universe, "always") == PromotionsServiceClient.DEFAULT_MTLS_ENDPOINT - assert PromotionsServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == PromotionsServiceClient.DEFAULT_MTLS_ENDPOINT - assert PromotionsServiceClient._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint - assert PromotionsServiceClient._get_api_endpoint(None, None, default_universe, "never") == default_endpoint - - with pytest.raises(MutualTLSChannelError) as excinfo: - PromotionsServiceClient._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto") - assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com." - - -def test__get_universe_domain(): - client_universe_domain = "foo.com" - universe_domain_env = "bar.com" - - assert PromotionsServiceClient._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain - assert PromotionsServiceClient._get_universe_domain(None, universe_domain_env) == universe_domain_env - assert PromotionsServiceClient._get_universe_domain(None, None) == PromotionsServiceClient._DEFAULT_UNIVERSE - - with pytest.raises(ValueError) as excinfo: - PromotionsServiceClient._get_universe_domain("", None) - assert str(excinfo.value) == "Universe Domain cannot be an empty string." - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc"), - (PromotionsServiceClient, transports.PromotionsServiceRestTransport, "rest"), -]) -def test__validate_universe_domain(client_class, transport_class, transport_name): - client = client_class( - transport=transport_class( - credentials=ga_credentials.AnonymousCredentials() - ) - ) - assert client._validate_universe_domain() == True - - # Test the case when universe is already validated. - assert client._validate_universe_domain() == True - - if transport_name == "grpc": - # Test the case where credentials are provided by the - # `local_channel_credentials`. The default universes in both match. - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - client = client_class(transport=transport_class(channel=channel)) - assert client._validate_universe_domain() == True - - # Test the case where credentials do not exist: e.g. a transport is provided - # with no credentials. Validation should still succeed because there is no - # mismatch with non-existent credentials. - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - transport=transport_class(channel=channel) - transport._credentials = None - client = client_class(transport=transport) - assert client._validate_universe_domain() == True - - # TODO: This is needed to cater for older versions of google-auth - # Make this test unconditional once the minimum supported version of - # google-auth becomes 2.23.0 or higher. - google_auth_major, google_auth_minor = [int(part) for part in google.auth.__version__.split(".")[0:2]] - if google_auth_major > 2 or (google_auth_major == 2 and google_auth_minor >= 23): - credentials = ga_credentials.AnonymousCredentials() - credentials._universe_domain = "foo.com" - # Test the case when there is a universe mismatch from the credentials. - client = client_class( - transport=transport_class(credentials=credentials) - ) - with pytest.raises(ValueError) as excinfo: - client._validate_universe_domain() - assert str(excinfo.value) == "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (foo.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." - - # Test the case when there is a universe mismatch from the client. - # - # TODO: Make this test unconditional once the minimum supported version of - # google-api-core becomes 2.15.0 or higher. - api_core_major, api_core_minor = [int(part) for part in api_core_version.__version__.split(".")[0:2]] - if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 15): - client = client_class(client_options={"universe_domain": "bar.com"}, transport=transport_class(credentials=ga_credentials.AnonymousCredentials(),)) - with pytest.raises(ValueError) as excinfo: - client._validate_universe_domain() - assert str(excinfo.value) == "The configured universe domain (bar.com) does not match the universe domain found in the credentials (googleapis.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." - - # Test that ValueError is raised if universe_domain is provided via client options and credentials is None - with pytest.raises(ValueError): - client._compare_universes("foo.bar", None) - - -@pytest.mark.parametrize("client_class,transport_name", [ - (PromotionsServiceClient, "grpc"), - (PromotionsServiceAsyncClient, "grpc_asyncio"), - (PromotionsServiceClient, "rest"), -]) -def test_promotions_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 == ( - 'merchantapi.googleapis.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else - 'https://merchantapi.googleapis.com' - ) - - -@pytest.mark.parametrize("transport_class,transport_name", [ - (transports.PromotionsServiceGrpcTransport, "grpc"), - (transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (transports.PromotionsServiceRestTransport, "rest"), -]) -def test_promotions_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", [ - (PromotionsServiceClient, "grpc"), - (PromotionsServiceAsyncClient, "grpc_asyncio"), - (PromotionsServiceClient, "rest"), -]) -def test_promotions_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 == ( - 'merchantapi.googleapis.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else - 'https://merchantapi.googleapis.com' - ) - - -def test_promotions_service_client_get_transport_class(): - transport = PromotionsServiceClient.get_transport_class() - available_transports = [ - transports.PromotionsServiceGrpcTransport, - transports.PromotionsServiceRestTransport, - ] - assert transport in available_transports - - transport = PromotionsServiceClient.get_transport_class("grpc") - assert transport == transports.PromotionsServiceGrpcTransport - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc"), - (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (PromotionsServiceClient, transports.PromotionsServiceRestTransport, "rest"), -]) -@mock.patch.object(PromotionsServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceClient)) -@mock.patch.object(PromotionsServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceAsyncClient)) -def test_promotions_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(PromotionsServiceClient, '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(PromotionsServiceClient, '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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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) as excinfo: - client = client_class(transport=transport_name) - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - # 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) as excinfo: - client = client_class(transport=transport_name) - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - - # 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - 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", [ - (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc", "true"), - (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), - (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc", "false"), - (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), - (PromotionsServiceClient, transports.PromotionsServiceRestTransport, "rest", "true"), - (PromotionsServiceClient, transports.PromotionsServiceRestTransport, "rest", "false"), -]) -@mock.patch.object(PromotionsServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceClient)) -@mock.patch.object(PromotionsServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceAsyncClient)) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_promotions_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) - 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) - 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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", [ - PromotionsServiceClient, PromotionsServiceAsyncClient -]) -@mock.patch.object(PromotionsServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PromotionsServiceClient)) -@mock.patch.object(PromotionsServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PromotionsServiceAsyncClient)) -def test_promotions_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 - - # 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) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - # 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) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - -@pytest.mark.parametrize("client_class", [ - PromotionsServiceClient, PromotionsServiceAsyncClient -]) -@mock.patch.object(PromotionsServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceClient)) -@mock.patch.object(PromotionsServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PromotionsServiceAsyncClient)) -def test_promotions_service_client_client_api_endpoint(client_class): - mock_client_cert_source = client_cert_source_callback - api_override = "foo.com" - default_universe = PromotionsServiceClient._DEFAULT_UNIVERSE - default_endpoint = PromotionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) - mock_universe = "bar.com" - mock_endpoint = PromotionsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) - - # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", - # use ClientOptions.api_endpoint as the api endpoint regardless. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel"): - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=api_override) - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == api_override - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", - # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - - # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), - # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, - # and ClientOptions.universe_domain="bar.com", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. - options = client_options.ClientOptions() - universe_exists = hasattr(options, "universe_domain") - if universe_exists: - options = client_options.ClientOptions(universe_domain=mock_universe) - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - else: - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == (mock_endpoint if universe_exists else default_endpoint) - assert client.universe_domain == (mock_universe if universe_exists else default_universe) - - # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - options = client_options.ClientOptions() - if hasattr(options, "universe_domain"): - delattr(options, "universe_domain") - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc"), - (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (PromotionsServiceClient, transports.PromotionsServiceRestTransport, "rest"), -]) -def test_promotions_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - 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", [ - (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc", grpc_helpers), - (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), - (PromotionsServiceClient, transports.PromotionsServiceRestTransport, "rest", None), -]) -def test_promotions_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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_promotions_service_client_client_options_from_dict(): - with mock.patch('google.shopping.merchant_promotions_v1beta.services.promotions_service.transports.PromotionsServiceGrpcTransport.__init__') as grpc_transport: - grpc_transport.return_value = None - client = PromotionsServiceClient( - 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", [ - (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport, "grpc", grpc_helpers), - (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), -]) -def test_promotions_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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( - "merchantapi.googleapis.com:443", - credentials=file_creds, - credentials_file=None, - quota_project_id=None, - default_scopes=( - 'https://www.googleapis.com/auth/content', -), - scopes=None, - default_host="merchantapi.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("request_type", [ - promotions.InsertPromotionRequest, - dict, -]) -def test_insert_promotion(request_type, transport: str = 'grpc'): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_promotion), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = promotions.Promotion( - name='name_value', - promotion_id='promotion_id_value', - content_language='content_language_value', - target_country='target_country_value', - redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], - data_source='data_source_value', - version_number=1518, - ) - response = client.insert_promotion(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = promotions.InsertPromotionRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, promotions.Promotion) - assert response.name == 'name_value' - assert response.promotion_id == 'promotion_id_value' - assert response.content_language == 'content_language_value' - assert response.target_country == 'target_country_value' - assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] - assert response.data_source == 'data_source_value' - assert response.version_number == 1518 - - -def test_insert_promotion_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = promotions.InsertPromotionRequest( - parent='parent_value', - data_source='data_source_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_promotion), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.insert_promotion(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == promotions.InsertPromotionRequest( - parent='parent_value', - data_source='data_source_value', - ) - -def test_insert_promotion_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.insert_promotion in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.insert_promotion] = mock_rpc - request = {} - client.insert_promotion(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.insert_promotion(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_insert_promotion_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.insert_promotion in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.insert_promotion] = mock_rpc - - request = {} - await client.insert_promotion(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.insert_promotion(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_insert_promotion_async(transport: str = 'grpc_asyncio', request_type=promotions.InsertPromotionRequest): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_promotion), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion( - name='name_value', - promotion_id='promotion_id_value', - content_language='content_language_value', - target_country='target_country_value', - redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], - data_source='data_source_value', - version_number=1518, - )) - response = await client.insert_promotion(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = promotions.InsertPromotionRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, promotions.Promotion) - assert response.name == 'name_value' - assert response.promotion_id == 'promotion_id_value' - assert response.content_language == 'content_language_value' - assert response.target_country == 'target_country_value' - assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] - assert response.data_source == 'data_source_value' - assert response.version_number == 1518 - - -@pytest.mark.asyncio -async def test_insert_promotion_async_from_dict(): - await test_insert_promotion_async(request_type=dict) - -def test_insert_promotion_field_headers(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = promotions.InsertPromotionRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_promotion), - '__call__') as call: - call.return_value = promotions.Promotion() - client.insert_promotion(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_insert_promotion_field_headers_async(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = promotions.InsertPromotionRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.insert_promotion), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion()) - await client.insert_promotion(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", [ - promotions.GetPromotionRequest, - dict, -]) -def test_get_promotion(request_type, transport: str = 'grpc'): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_promotion), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = promotions.Promotion( - name='name_value', - promotion_id='promotion_id_value', - content_language='content_language_value', - target_country='target_country_value', - redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], - data_source='data_source_value', - version_number=1518, - ) - response = client.get_promotion(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = promotions.GetPromotionRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, promotions.Promotion) - assert response.name == 'name_value' - assert response.promotion_id == 'promotion_id_value' - assert response.content_language == 'content_language_value' - assert response.target_country == 'target_country_value' - assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] - assert response.data_source == 'data_source_value' - assert response.version_number == 1518 - - -def test_get_promotion_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = promotions.GetPromotionRequest( - name='name_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_promotion), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.get_promotion(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == promotions.GetPromotionRequest( - name='name_value', - ) - -def test_get_promotion_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_promotion in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.get_promotion] = mock_rpc - request = {} - client.get_promotion(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.get_promotion(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_get_promotion_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.get_promotion in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.get_promotion] = mock_rpc - - request = {} - await client.get_promotion(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.get_promotion(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_get_promotion_async(transport: str = 'grpc_asyncio', request_type=promotions.GetPromotionRequest): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_promotion), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion( - name='name_value', - promotion_id='promotion_id_value', - content_language='content_language_value', - target_country='target_country_value', - redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], - data_source='data_source_value', - version_number=1518, - )) - response = await client.get_promotion(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = promotions.GetPromotionRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, promotions.Promotion) - assert response.name == 'name_value' - assert response.promotion_id == 'promotion_id_value' - assert response.content_language == 'content_language_value' - assert response.target_country == 'target_country_value' - assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] - assert response.data_source == 'data_source_value' - assert response.version_number == 1518 - - -@pytest.mark.asyncio -async def test_get_promotion_async_from_dict(): - await test_get_promotion_async(request_type=dict) - -def test_get_promotion_field_headers(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = promotions.GetPromotionRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_promotion), - '__call__') as call: - call.return_value = promotions.Promotion() - client.get_promotion(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_promotion_field_headers_async(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = promotions.GetPromotionRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_promotion), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion()) - await client.get_promotion(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_promotion_flattened(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_promotion), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = promotions.Promotion() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.get_promotion( - 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_promotion_flattened_error(): - client = PromotionsServiceClient( - 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_promotion( - promotions.GetPromotionRequest(), - name='name_value', - ) - -@pytest.mark.asyncio -async def test_get_promotion_flattened_async(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_promotion), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = promotions.Promotion() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.get_promotion( - 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_promotion_flattened_error_async(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.get_promotion( - promotions.GetPromotionRequest(), - name='name_value', - ) - - -@pytest.mark.parametrize("request_type", [ - promotions.ListPromotionsRequest, - dict, -]) -def test_list_promotions(request_type, transport: str = 'grpc'): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_promotions), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = promotions.ListPromotionsResponse( - next_page_token='next_page_token_value', - ) - response = client.list_promotions(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = promotions.ListPromotionsRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListPromotionsPager) - assert response.next_page_token == 'next_page_token_value' - - -def test_list_promotions_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = promotions.ListPromotionsRequest( - parent='parent_value', - page_token='page_token_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_promotions), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.list_promotions(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == promotions.ListPromotionsRequest( - parent='parent_value', - page_token='page_token_value', - ) - -def test_list_promotions_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_promotions in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.list_promotions] = mock_rpc - request = {} - client.list_promotions(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_promotions(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_promotions_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.list_promotions in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.list_promotions] = mock_rpc - - request = {} - await client.list_promotions(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.list_promotions(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_promotions_async(transport: str = 'grpc_asyncio', request_type=promotions.ListPromotionsRequest): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_promotions), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(promotions.ListPromotionsResponse( - next_page_token='next_page_token_value', - )) - response = await client.list_promotions(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = promotions.ListPromotionsRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListPromotionsAsyncPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.asyncio -async def test_list_promotions_async_from_dict(): - await test_list_promotions_async(request_type=dict) - -def test_list_promotions_field_headers(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = promotions.ListPromotionsRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_promotions), - '__call__') as call: - call.return_value = promotions.ListPromotionsResponse() - client.list_promotions(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_promotions_field_headers_async(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = promotions.ListPromotionsRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_promotions), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.ListPromotionsResponse()) - await client.list_promotions(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_promotions_flattened(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_promotions), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = promotions.ListPromotionsResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.list_promotions( - 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_promotions_flattened_error(): - client = PromotionsServiceClient( - 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_promotions( - promotions.ListPromotionsRequest(), - parent='parent_value', - ) - -@pytest.mark.asyncio -async def test_list_promotions_flattened_async(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_promotions), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = promotions.ListPromotionsResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.ListPromotionsResponse()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.list_promotions( - 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_promotions_flattened_error_async(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.list_promotions( - promotions.ListPromotionsRequest(), - parent='parent_value', - ) - - -def test_list_promotions_pager(transport_name: str = "grpc"): - client = PromotionsServiceClient( - 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_promotions), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - promotions.Promotion(), - promotions.Promotion(), - ], - next_page_token='abc', - ), - promotions.ListPromotionsResponse( - promotions=[], - next_page_token='def', - ), - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - ], - next_page_token='ghi', - ), - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - promotions.Promotion(), - ], - ), - RuntimeError, - ) - - expected_metadata = () - retry = retries.Retry() - timeout = 5 - expected_metadata = tuple(expected_metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ('parent', ''), - )), - ) - pager = client.list_promotions(request={}, retry=retry, timeout=timeout) - - assert pager._metadata == expected_metadata - assert pager._retry == retry - assert pager._timeout == timeout - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, promotions.Promotion) - for i in results) -def test_list_promotions_pages(transport_name: str = "grpc"): - client = PromotionsServiceClient( - 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_promotions), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - promotions.Promotion(), - promotions.Promotion(), - ], - next_page_token='abc', - ), - promotions.ListPromotionsResponse( - promotions=[], - next_page_token='def', - ), - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - ], - next_page_token='ghi', - ), - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - promotions.Promotion(), - ], - ), - RuntimeError, - ) - pages = list(client.list_promotions(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_promotions_async_pager(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_promotions), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - promotions.Promotion(), - promotions.Promotion(), - ], - next_page_token='abc', - ), - promotions.ListPromotionsResponse( - promotions=[], - next_page_token='def', - ), - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - ], - next_page_token='ghi', - ), - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - promotions.Promotion(), - ], - ), - RuntimeError, - ) - async_pager = await client.list_promotions(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, promotions.Promotion) - for i in responses) - - -@pytest.mark.asyncio -async def test_list_promotions_async_pages(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_promotions), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - promotions.Promotion(), - promotions.Promotion(), - ], - next_page_token='abc', - ), - promotions.ListPromotionsResponse( - promotions=[], - next_page_token='def', - ), - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - ], - next_page_token='ghi', - ), - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - promotions.Promotion(), - ], - ), - 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_promotions(request={}) - ).pages: - pages.append(page_) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - - -def test_insert_promotion_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.insert_promotion in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.insert_promotion] = mock_rpc - - request = {} - client.insert_promotion(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.insert_promotion(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_insert_promotion_rest_required_fields(request_type=promotions.InsertPromotionRequest): - transport_class = transports.PromotionsServiceRestTransport - - request_init = {} - request_init["parent"] = "" - request_init["data_source"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads(json_format.MessageToJson( - pb_request, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).insert_promotion._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["dataSource"] = 'data_source_value' - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).insert_promotion._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 "dataSource" in jsonified_request - assert jsonified_request["dataSource"] == 'data_source_value' - - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = promotions.Promotion() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "post", - 'query_params': pb_request, - } - transcode_result['body'] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = promotions.Promotion.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.insert_promotion(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_insert_promotion_rest_unset_required_fields(): - transport = transports.PromotionsServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.insert_promotion._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("parent", "promotion", "dataSource", ))) - - -def test_get_promotion_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_promotion in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.get_promotion] = mock_rpc - - request = {} - client.get_promotion(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.get_promotion(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_get_promotion_rest_required_fields(request_type=promotions.GetPromotionRequest): - transport_class = transports.PromotionsServiceRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_promotion._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_promotion._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 = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = promotions.Promotion() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "get", - 'query_params': pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = promotions.Promotion.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.get_promotion(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_get_promotion_rest_unset_required_fields(): - transport = transports.PromotionsServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.get_promotion._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name", ))) - - -def test_get_promotion_rest_flattened(): - client = PromotionsServiceClient( - 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 = promotions.Promotion() - - # get arguments that satisfy an http rule for this method - sample_request = {'name': 'accounts/sample1/promotions/sample2'} - - # get truthy value for each flattened field - mock_args = dict( - name='name_value', - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = promotions.Promotion.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.get_promotion(**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/promotions/v1beta/{name=accounts/*/promotions/*}" % client.transport._host, args[1]) - - -def test_get_promotion_rest_flattened_error(transport: str = 'rest'): - client = PromotionsServiceClient( - 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_promotion( - promotions.GetPromotionRequest(), - name='name_value', - ) - - -def test_list_promotions_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_promotions in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.list_promotions] = mock_rpc - - request = {} - client.list_promotions(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_promotions(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_list_promotions_rest_required_fields(request_type=promotions.ListPromotionsRequest): - transport_class = transports.PromotionsServiceRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_promotions._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_promotions._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 = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = promotions.ListPromotionsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "get", - 'query_params': pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = promotions.ListPromotionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.list_promotions(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_list_promotions_rest_unset_required_fields(): - transport = transports.PromotionsServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.list_promotions._get_unset_required_fields({}) - assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) - - -def test_list_promotions_rest_flattened(): - client = PromotionsServiceClient( - 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 = promotions.ListPromotionsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {'parent': 'accounts/sample1'} - - # get truthy value for each flattened field - mock_args = dict( - parent='parent_value', - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = promotions.ListPromotionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.list_promotions(**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/promotions/v1beta/{parent=accounts/*}/promotions" % client.transport._host, args[1]) - - -def test_list_promotions_rest_flattened_error(transport: str = 'rest'): - client = PromotionsServiceClient( - 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_promotions( - promotions.ListPromotionsRequest(), - parent='parent_value', - ) - - -def test_list_promotions_rest_pager(transport: str = 'rest'): - client = PromotionsServiceClient( - 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 = ( - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - promotions.Promotion(), - promotions.Promotion(), - ], - next_page_token='abc', - ), - promotions.ListPromotionsResponse( - promotions=[], - next_page_token='def', - ), - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - ], - next_page_token='ghi', - ), - promotions.ListPromotionsResponse( - promotions=[ - promotions.Promotion(), - promotions.Promotion(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(promotions.ListPromotionsResponse.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': 'accounts/sample1'} - - pager = client.list_promotions(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, promotions.Promotion) - for i in results) - - pages = list(client.list_promotions(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.PromotionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.PromotionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PromotionsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.PromotionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = PromotionsServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = PromotionsServiceClient( - client_options=options, - credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.PromotionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PromotionsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.PromotionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = PromotionsServiceClient(transport=transport) - assert client.transport is transport - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.PromotionsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.PromotionsServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize("transport_class", [ - transports.PromotionsServiceGrpcTransport, - transports.PromotionsServiceGrpcAsyncIOTransport, - transports.PromotionsServiceRestTransport, -]) -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() - -def test_transport_kind_grpc(): - transport = PromotionsServiceClient.get_transport_class("grpc")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "grpc" - - -def test_initialize_client_w_grpc(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_insert_promotion_empty_call_grpc(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.insert_promotion), - '__call__') as call: - call.return_value = promotions.Promotion() - client.insert_promotion(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = promotions.InsertPromotionRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_promotion_empty_call_grpc(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_promotion), - '__call__') as call: - call.return_value = promotions.Promotion() - client.get_promotion(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = promotions.GetPromotionRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_promotions_empty_call_grpc(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_promotions), - '__call__') as call: - call.return_value = promotions.ListPromotionsResponse() - client.list_promotions(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = promotions.ListPromotionsRequest() - - assert args[0] == request_msg - - -def test_transport_kind_grpc_asyncio(): - transport = PromotionsServiceAsyncClient.get_transport_class("grpc_asyncio")( - credentials=async_anonymous_credentials() - ) - assert transport.kind == "grpc_asyncio" - - -def test_initialize_client_w_grpc_asyncio(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_insert_promotion_empty_call_grpc_asyncio(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.insert_promotion), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion( - name='name_value', - promotion_id='promotion_id_value', - content_language='content_language_value', - target_country='target_country_value', - redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], - data_source='data_source_value', - version_number=1518, - )) - await client.insert_promotion(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = promotions.InsertPromotionRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_promotion_empty_call_grpc_asyncio(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_promotion), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.Promotion( - name='name_value', - promotion_id='promotion_id_value', - content_language='content_language_value', - target_country='target_country_value', - redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], - data_source='data_source_value', - version_number=1518, - )) - await client.get_promotion(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = promotions.GetPromotionRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_promotions_empty_call_grpc_asyncio(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_promotions), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(promotions.ListPromotionsResponse( - next_page_token='next_page_token_value', - )) - await client.list_promotions(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = promotions.ListPromotionsRequest() - - assert args[0] == request_msg - - -def test_transport_kind_rest(): - transport = PromotionsServiceClient.get_transport_class("rest")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "rest" - - -def test_insert_promotion_rest_bad_request(request_type=promotions.InsertPromotionRequest): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'parent': 'accounts/sample1'} - 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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.insert_promotion(request) - - -@pytest.mark.parametrize("request_type", [ - promotions.InsertPromotionRequest, - dict, -]) -def test_insert_promotion_rest_call_success(request_type): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'parent': 'accounts/sample1'} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), 'request') as req: - # Designate an appropriate value for the returned response. - return_value = promotions.Promotion( - name='name_value', - promotion_id='promotion_id_value', - content_language='content_language_value', - target_country='target_country_value', - redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], - data_source='data_source_value', - version_number=1518, - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = promotions.Promotion.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.insert_promotion(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, promotions.Promotion) - assert response.name == 'name_value' - assert response.promotion_id == 'promotion_id_value' - assert response.content_language == 'content_language_value' - assert response.target_country == 'target_country_value' - assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] - assert response.data_source == 'data_source_value' - assert response.version_number == 1518 - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_insert_promotion_rest_interceptors(null_interceptor): - transport = transports.PromotionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.PromotionsServiceRestInterceptor(), - ) - client = PromotionsServiceClient(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.PromotionsServiceRestInterceptor, "post_insert_promotion") as post, \ - mock.patch.object(transports.PromotionsServiceRestInterceptor, "pre_insert_promotion") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = promotions.InsertPromotionRequest.pb(promotions.InsertPromotionRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = promotions.Promotion.to_json(promotions.Promotion()) - req.return_value.content = return_value - - request = promotions.InsertPromotionRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = promotions.Promotion() - - client.insert_promotion(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_promotion_rest_bad_request(request_type=promotions.GetPromotionRequest): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'name': 'accounts/sample1/promotions/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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.get_promotion(request) - - -@pytest.mark.parametrize("request_type", [ - promotions.GetPromotionRequest, - dict, -]) -def test_get_promotion_rest_call_success(request_type): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'name': 'accounts/sample1/promotions/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 = promotions.Promotion( - name='name_value', - promotion_id='promotion_id_value', - content_language='content_language_value', - target_country='target_country_value', - redemption_channel=[promotions_common.RedemptionChannel.IN_STORE], - data_source='data_source_value', - version_number=1518, - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = promotions.Promotion.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.get_promotion(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, promotions.Promotion) - assert response.name == 'name_value' - assert response.promotion_id == 'promotion_id_value' - assert response.content_language == 'content_language_value' - assert response.target_country == 'target_country_value' - assert response.redemption_channel == [promotions_common.RedemptionChannel.IN_STORE] - assert response.data_source == 'data_source_value' - assert response.version_number == 1518 - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_promotion_rest_interceptors(null_interceptor): - transport = transports.PromotionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.PromotionsServiceRestInterceptor(), - ) - client = PromotionsServiceClient(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.PromotionsServiceRestInterceptor, "post_get_promotion") as post, \ - mock.patch.object(transports.PromotionsServiceRestInterceptor, "pre_get_promotion") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = promotions.GetPromotionRequest.pb(promotions.GetPromotionRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = promotions.Promotion.to_json(promotions.Promotion()) - req.return_value.content = return_value - - request = promotions.GetPromotionRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = promotions.Promotion() - - client.get_promotion(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_promotions_rest_bad_request(request_type=promotions.ListPromotionsRequest): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'parent': 'accounts/sample1'} - 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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.list_promotions(request) - - -@pytest.mark.parametrize("request_type", [ - promotions.ListPromotionsRequest, - dict, -]) -def test_list_promotions_rest_call_success(request_type): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'parent': 'accounts/sample1'} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), 'request') as req: - # Designate an appropriate value for the returned response. - return_value = promotions.ListPromotionsResponse( - next_page_token='next_page_token_value', - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = promotions.ListPromotionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.list_promotions(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListPromotionsPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_promotions_rest_interceptors(null_interceptor): - transport = transports.PromotionsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.PromotionsServiceRestInterceptor(), - ) - client = PromotionsServiceClient(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.PromotionsServiceRestInterceptor, "post_list_promotions") as post, \ - mock.patch.object(transports.PromotionsServiceRestInterceptor, "pre_list_promotions") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = promotions.ListPromotionsRequest.pb(promotions.ListPromotionsRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = promotions.ListPromotionsResponse.to_json(promotions.ListPromotionsResponse()) - req.return_value.content = return_value - - request = promotions.ListPromotionsRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = promotions.ListPromotionsResponse() - - client.list_promotions(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - -def test_initialize_client_w_rest(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_insert_promotion_empty_call_rest(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.insert_promotion), - '__call__') as call: - client.insert_promotion(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = promotions.InsertPromotionRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_promotion_empty_call_rest(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_promotion), - '__call__') as call: - client.get_promotion(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = promotions.GetPromotionRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_promotions_empty_call_rest(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_promotions), - '__call__') as call: - client.list_promotions(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = promotions.ListPromotionsRequest() - - assert args[0] == request_msg - - -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert isinstance( - client.transport, - transports.PromotionsServiceGrpcTransport, - ) - -def test_promotions_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.PromotionsServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json" - ) - - -def test_promotions_service_base_transport(): - # Instantiate the base transport. - with mock.patch('google.shopping.merchant_promotions_v1beta.services.promotions_service.transports.PromotionsServiceTransport.__init__') as Transport: - Transport.return_value = None - transport = transports.PromotionsServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - 'insert_promotion', - 'get_promotion', - 'list_promotions', - ) - 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_promotions_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.shopping.merchant_promotions_v1beta.services.promotions_service.transports.PromotionsServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.PromotionsServiceTransport( - 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/content', -), - quota_project_id="octopus", - ) - - -def test_promotions_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.shopping.merchant_promotions_v1beta.services.promotions_service.transports.PromotionsServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.PromotionsServiceTransport() - adc.assert_called_once() - - -def test_promotions_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) - PromotionsServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/content', -), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.PromotionsServiceGrpcTransport, - transports.PromotionsServiceGrpcAsyncIOTransport, - ], -) -def test_promotions_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/content',), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.PromotionsServiceGrpcTransport, - transports.PromotionsServiceGrpcAsyncIOTransport, - transports.PromotionsServiceRestTransport, - ], -) -def test_promotions_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.PromotionsServiceGrpcTransport, grpc_helpers), - (transports.PromotionsServiceGrpcAsyncIOTransport, grpc_helpers_async) - ], -) -def test_promotions_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( - "merchantapi.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=( - 'https://www.googleapis.com/auth/content', -), - scopes=["1", "2"], - default_host="merchantapi.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("transport_class", [transports.PromotionsServiceGrpcTransport, transports.PromotionsServiceGrpcAsyncIOTransport]) -def test_promotions_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_promotions_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.PromotionsServiceRestTransport ( - 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_promotions_service_host_no_port(transport_name): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='merchantapi.googleapis.com'), - transport=transport_name, - ) - assert client.transport._host == ( - 'merchantapi.googleapis.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else 'https://merchantapi.googleapis.com' - ) - -@pytest.mark.parametrize("transport_name", [ - "grpc", - "grpc_asyncio", - "rest", -]) -def test_promotions_service_host_with_port(transport_name): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='merchantapi.googleapis.com:8000'), - transport=transport_name, - ) - assert client.transport._host == ( - 'merchantapi.googleapis.com:8000' - if transport_name in ['grpc', 'grpc_asyncio'] - else 'https://merchantapi.googleapis.com:8000' - ) - -@pytest.mark.parametrize("transport_name", [ - "rest", -]) -def test_promotions_service_client_transport_session_collision(transport_name): - creds1 = ga_credentials.AnonymousCredentials() - creds2 = ga_credentials.AnonymousCredentials() - client1 = PromotionsServiceClient( - credentials=creds1, - transport=transport_name, - ) - client2 = PromotionsServiceClient( - credentials=creds2, - transport=transport_name, - ) - session1 = client1.transport.insert_promotion._session - session2 = client2.transport.insert_promotion._session - assert session1 != session2 - session1 = client1.transport.get_promotion._session - session2 = client2.transport.get_promotion._session - assert session1 != session2 - session1 = client1.transport.list_promotions._session - session2 = client2.transport.list_promotions._session - assert session1 != session2 -def test_promotions_service_grpc_transport_channel(): - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.PromotionsServiceGrpcTransport( - 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_promotions_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.PromotionsServiceGrpcAsyncIOTransport( - 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.PromotionsServiceGrpcTransport, transports.PromotionsServiceGrpcAsyncIOTransport]) -def test_promotions_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.PromotionsServiceGrpcTransport, transports.PromotionsServiceGrpcAsyncIOTransport]) -def test_promotions_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_promotion_path(): - account = "squid" - promotion = "clam" - expected = "accounts/{account}/promotions/{promotion}".format(account=account, promotion=promotion, ) - actual = PromotionsServiceClient.promotion_path(account, promotion) - assert expected == actual - - -def test_parse_promotion_path(): - expected = { - "account": "whelk", - "promotion": "octopus", - } - path = PromotionsServiceClient.promotion_path(**expected) - - # Check that the path construction is reversible. - actual = PromotionsServiceClient.parse_promotion_path(path) - assert expected == actual - -def test_common_billing_account_path(): - billing_account = "oyster" - expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - actual = PromotionsServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "nudibranch", - } - path = PromotionsServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = PromotionsServiceClient.parse_common_billing_account_path(path) - assert expected == actual - -def test_common_folder_path(): - folder = "cuttlefish" - expected = "folders/{folder}".format(folder=folder, ) - actual = PromotionsServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "mussel", - } - path = PromotionsServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = PromotionsServiceClient.parse_common_folder_path(path) - assert expected == actual - -def test_common_organization_path(): - organization = "winkle" - expected = "organizations/{organization}".format(organization=organization, ) - actual = PromotionsServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "nautilus", - } - path = PromotionsServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = PromotionsServiceClient.parse_common_organization_path(path) - assert expected == actual - -def test_common_project_path(): - project = "scallop" - expected = "projects/{project}".format(project=project, ) - actual = PromotionsServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "abalone", - } - path = PromotionsServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = PromotionsServiceClient.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 = PromotionsServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "whelk", - "location": "octopus", - } - path = PromotionsServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = PromotionsServiceClient.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.PromotionsServiceTransport, '_prep_wrapped_messages') as prep: - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object(transports.PromotionsServiceTransport, '_prep_wrapped_messages') as prep: - transport_class = PromotionsServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -def test_transport_close_grpc(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc" - ) - with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -@pytest.mark.asyncio -async def test_transport_close_grpc_asyncio(): - client = PromotionsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio" - ) - with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: - async with client: - close.assert_not_called() - close.assert_called_once() - - -def test_transport_close_rest(): - client = PromotionsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - with mock.patch.object(type(getattr(client.transport, "_session")), "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 = PromotionsServiceClient( - 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", [ - (PromotionsServiceClient, transports.PromotionsServiceGrpcTransport), - (PromotionsServiceAsyncClient, transports.PromotionsServiceGrpcAsyncIOTransport), -]) -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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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/google-shopping-merchant-quota/v1beta/.coveragerc b/owl-bot-staging/google-shopping-merchant-quota/v1beta/.coveragerc deleted file mode 100644 index 8114816bc3c5..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/.coveragerc +++ /dev/null @@ -1,13 +0,0 @@ -[run] -branch = True - -[report] -show_missing = True -omit = - google/shopping/merchant_quota/__init__.py - google/shopping/merchant_quota/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/google-shopping-merchant-quota/v1beta/.flake8 b/owl-bot-staging/google-shopping-merchant-quota/v1beta/.flake8 deleted file mode 100644 index 29227d4cf419..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/.flake8 +++ /dev/null @@ -1,33 +0,0 @@ -# -*- 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/google-shopping-merchant-quota/v1beta/MANIFEST.in b/owl-bot-staging/google-shopping-merchant-quota/v1beta/MANIFEST.in deleted file mode 100644 index e1f38916c325..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -recursive-include google/shopping/merchant_quota *.py -recursive-include google/shopping/merchant_quota_v1beta *.py diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/README.rst b/owl-bot-staging/google-shopping-merchant-quota/v1beta/README.rst deleted file mode 100644 index ffa65e82132a..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/README.rst +++ /dev/null @@ -1,49 +0,0 @@ -Python Client for Google Shopping Merchant Quota 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 Shopping Merchant Quota 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/google-shopping-merchant-quota/v1beta/docs/_static/custom.css b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/_static/custom.css deleted file mode 100644 index 06423be0b592..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/_static/custom.css +++ /dev/null @@ -1,3 +0,0 @@ -dl.field-list > dt { - min-width: 100px -} diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/conf.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/conf.py deleted file mode 100644 index a76827c00d4d..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/conf.py +++ /dev/null @@ -1,376 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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-shopping-merchant-quota 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-shopping-merchant-quota" -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 Shopping 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-shopping-merchant-quota-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-shopping-merchant-quota.tex", - u"google-shopping-merchant-quota 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-shopping-merchant-quota", - u"Google Shopping Merchant Quota 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-shopping-merchant-quota", - u"google-shopping-merchant-quota Documentation", - author, - "google-shopping-merchant-quota", - "GAPIC library for Google Shopping Merchant Quota 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/google-shopping-merchant-quota/v1beta/docs/index.rst b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/index.rst deleted file mode 100644 index c688ba3396e1..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/index.rst +++ /dev/null @@ -1,7 +0,0 @@ -API Reference -------------- -.. toctree:: - :maxdepth: 2 - - merchant_quota_v1beta/services_ - merchant_quota_v1beta/types_ diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/quota_service.rst b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/quota_service.rst deleted file mode 100644 index 1743e25da211..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/quota_service.rst +++ /dev/null @@ -1,10 +0,0 @@ -QuotaService ------------------------------- - -.. automodule:: google.shopping.merchant_quota_v1beta.services.quota_service - :members: - :inherited-members: - -.. automodule:: google.shopping.merchant_quota_v1beta.services.quota_service.pagers - :members: - :inherited-members: diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/services_.rst b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/services_.rst deleted file mode 100644 index 0928f3a6f1ce..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/services_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Services for Google Shopping Merchant Quota v1beta API -====================================================== -.. toctree:: - :maxdepth: 2 - - quota_service diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/types_.rst b/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/types_.rst deleted file mode 100644 index 622859fdaffb..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/docs/merchant_quota_v1beta/types_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Types for Google Shopping Merchant Quota v1beta API -=================================================== - -.. automodule:: google.shopping.merchant_quota_v1beta.types - :members: - :show-inheritance: diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/__init__.py deleted file mode 100644 index c3a300a10746..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/__init__.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.shopping.merchant_quota import gapic_version as package_version - -__version__ = package_version.__version__ - - -from google.shopping.merchant_quota_v1beta.services.quota_service.client import QuotaServiceClient -from google.shopping.merchant_quota_v1beta.services.quota_service.async_client import QuotaServiceAsyncClient - -from google.shopping.merchant_quota_v1beta.types.quota import ListQuotaGroupsRequest -from google.shopping.merchant_quota_v1beta.types.quota import ListQuotaGroupsResponse -from google.shopping.merchant_quota_v1beta.types.quota import MethodDetails -from google.shopping.merchant_quota_v1beta.types.quota import QuotaGroup - -__all__ = ('QuotaServiceClient', - 'QuotaServiceAsyncClient', - 'ListQuotaGroupsRequest', - 'ListQuotaGroupsResponse', - 'MethodDetails', - 'QuotaGroup', -) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/gapic_version.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/gapic_version.py deleted file mode 100644 index 558c8aab67c5..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/gapic_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/py.typed b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/py.typed deleted file mode 100644 index c73143bc3edf..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-shopping-merchant-quota package uses inline types. diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/__init__.py deleted file mode 100644 index d5c60977b344..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/__init__.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.shopping.merchant_quota_v1beta import gapic_version as package_version - -__version__ = package_version.__version__ - - -from .services.quota_service import QuotaServiceClient -from .services.quota_service import QuotaServiceAsyncClient - -from .types.quota import ListQuotaGroupsRequest -from .types.quota import ListQuotaGroupsResponse -from .types.quota import MethodDetails -from .types.quota import QuotaGroup - -__all__ = ( - 'QuotaServiceAsyncClient', -'ListQuotaGroupsRequest', -'ListQuotaGroupsResponse', -'MethodDetails', -'QuotaGroup', -'QuotaServiceClient', -) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_metadata.json b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_metadata.json deleted file mode 100644 index 8278f93d2b60..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_metadata.json +++ /dev/null @@ -1,43 +0,0 @@ - { - "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", - "language": "python", - "libraryPackage": "google.shopping.merchant_quota_v1beta", - "protoPackage": "google.shopping.merchant.quota.v1beta", - "schema": "1.0", - "services": { - "QuotaService": { - "clients": { - "grpc": { - "libraryClient": "QuotaServiceClient", - "rpcs": { - "ListQuotaGroups": { - "methods": [ - "list_quota_groups" - ] - } - } - }, - "grpc-async": { - "libraryClient": "QuotaServiceAsyncClient", - "rpcs": { - "ListQuotaGroups": { - "methods": [ - "list_quota_groups" - ] - } - } - }, - "rest": { - "libraryClient": "QuotaServiceClient", - "rpcs": { - "ListQuotaGroups": { - "methods": [ - "list_quota_groups" - ] - } - } - } - } - } - } -} diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_version.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_version.py deleted file mode 100644 index 558c8aab67c5..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/gapic_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/py.typed b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/py.typed deleted file mode 100644 index c73143bc3edf..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-shopping-merchant-quota package uses inline types. diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/__init__.py deleted file mode 100644 index 8f6cf068242c..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/__init__.py deleted file mode 100644 index 512b8ee436f7..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 QuotaServiceClient -from .async_client import QuotaServiceAsyncClient - -__all__ = ( - 'QuotaServiceClient', - 'QuotaServiceAsyncClient', -) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/async_client.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/async_client.py deleted file mode 100644 index 7c54e59b44d4..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/async_client.py +++ /dev/null @@ -1,360 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 re -from typing import Dict, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union - -from google.shopping.merchant_quota_v1beta 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_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - - -try: - OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.shopping.merchant_quota_v1beta.services.quota_service import pagers -from google.shopping.merchant_quota_v1beta.types import quota -from .transports.base import QuotaServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc_asyncio import QuotaServiceGrpcAsyncIOTransport -from .client import QuotaServiceClient - - -class QuotaServiceAsyncClient: - """Service to get method call quota information per Merchant API - method. - """ - - _client: QuotaServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = QuotaServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = QuotaServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = QuotaServiceClient._DEFAULT_ENDPOINT_TEMPLATE - _DEFAULT_UNIVERSE = QuotaServiceClient._DEFAULT_UNIVERSE - - quota_group_path = staticmethod(QuotaServiceClient.quota_group_path) - parse_quota_group_path = staticmethod(QuotaServiceClient.parse_quota_group_path) - common_billing_account_path = staticmethod(QuotaServiceClient.common_billing_account_path) - parse_common_billing_account_path = staticmethod(QuotaServiceClient.parse_common_billing_account_path) - common_folder_path = staticmethod(QuotaServiceClient.common_folder_path) - parse_common_folder_path = staticmethod(QuotaServiceClient.parse_common_folder_path) - common_organization_path = staticmethod(QuotaServiceClient.common_organization_path) - parse_common_organization_path = staticmethod(QuotaServiceClient.parse_common_organization_path) - common_project_path = staticmethod(QuotaServiceClient.common_project_path) - parse_common_project_path = staticmethod(QuotaServiceClient.parse_common_project_path) - common_location_path = staticmethod(QuotaServiceClient.common_location_path) - parse_common_location_path = staticmethod(QuotaServiceClient.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: - QuotaServiceAsyncClient: The constructed client. - """ - return QuotaServiceClient.from_service_account_info.__func__(QuotaServiceAsyncClient, 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: - QuotaServiceAsyncClient: The constructed client. - """ - return QuotaServiceClient.from_service_account_file.__func__(QuotaServiceAsyncClient, 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 QuotaServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> QuotaServiceTransport: - """Returns the transport used by the client instance. - - Returns: - QuotaServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = QuotaServiceClient.get_transport_class - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[Union[str, QuotaServiceTransport, Callable[..., QuotaServiceTransport]]] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the quota service async 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 (Optional[Union[str,QuotaServiceTransport,Callable[..., QuotaServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the QuotaServiceTransport constructor. - 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. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "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). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS 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. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - 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. - """ - self._client = QuotaServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - - ) - - async def list_quota_groups(self, - request: Optional[Union[quota.ListQuotaGroupsRequest, 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.ListQuotaGroupsAsyncPager: - r"""Lists the daily call quota and usage per group for - your Merchant Center account. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.shopping import merchant_quota_v1beta - - async def sample_list_quota_groups(): - # Create a client - client = merchant_quota_v1beta.QuotaServiceAsyncClient() - - # Initialize request argument(s) - request = merchant_quota_v1beta.ListQuotaGroupsRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_quota_groups(request=request) - - # Handle the response - async for response in page_result: - print(response) - - Args: - request (Optional[Union[google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsRequest, dict]]): - The request object. Request message for the - ListQuotaGroups method. - parent (:class:`str`): - Required. The merchant account who - owns the collection of method quotas - Format: accounts/{account} - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.shopping.merchant_quota_v1beta.services.quota_service.pagers.ListQuotaGroupsAsyncPager: - Response message for the - ListMethodGroups 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.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, quota.ListQuotaGroupsRequest): - request = quota.ListQuotaGroupsRequest(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._client._transport._wrapped_methods[self._client._transport.list_quota_groups] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # 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.ListQuotaGroupsAsyncPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "QuotaServiceAsyncClient": - 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__ = ( - "QuotaServiceAsyncClient", -) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/client.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/client.py deleted file mode 100644 index 0d09cf485cfe..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/client.py +++ /dev/null @@ -1,716 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.shopping.merchant_quota_v1beta 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, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - -from google.shopping.merchant_quota_v1beta.services.quota_service import pagers -from google.shopping.merchant_quota_v1beta.types import quota -from .transports.base import QuotaServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import QuotaServiceGrpcTransport -from .transports.grpc_asyncio import QuotaServiceGrpcAsyncIOTransport -from .transports.rest import QuotaServiceRestTransport - - -class QuotaServiceClientMeta(type): - """Metaclass for the QuotaService 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[QuotaServiceTransport]] - _transport_registry["grpc"] = QuotaServiceGrpcTransport - _transport_registry["grpc_asyncio"] = QuotaServiceGrpcAsyncIOTransport - _transport_registry["rest"] = QuotaServiceRestTransport - - def get_transport_class(cls, - label: Optional[str] = None, - ) -> Type[QuotaServiceTransport]: - """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 QuotaServiceClient(metaclass=QuotaServiceClientMeta): - """Service to get method call quota information per Merchant API - method. - """ - - @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") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "merchantapi.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "merchantapi.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @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: - QuotaServiceClient: 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: - QuotaServiceClient: 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) -> QuotaServiceTransport: - """Returns the transport used by the client instance. - - Returns: - QuotaServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def quota_group_path(account: str,group: str,) -> str: - """Returns a fully-qualified quota_group string.""" - return "accounts/{account}/groups/{group}".format(account=account, group=group, ) - - @staticmethod - def parse_quota_group_path(path: str) -> Dict[str,str]: - """Parses a quota_group path into its component segments.""" - m = re.match(r"^accounts/(?P.+?)/groups/(?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): - """Deprecated. 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. - """ - - warnings.warn("get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning) - 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 - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false").lower() - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - 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`") - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint(api_override, client_cert_source, universe_domain, use_mtls_endpoint): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): - _default_universe = QuotaServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError(f"mTLS is not supported in any universe other than {_default_universe}.") - api_endpoint = QuotaServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = QuotaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=universe_domain) - return api_endpoint - - @staticmethod - def _get_universe_domain(client_universe_domain: Optional[str], universe_domain_env: Optional[str]) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = QuotaServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - @staticmethod - def _compare_universes(client_universe: str, - credentials: ga_credentials.Credentials) -> bool: - """Returns True iff the universe domains used by the client and credentials match. - - Args: - client_universe (str): The universe domain configured via the client options. - credentials (ga_credentials.Credentials): The credentials being used in the client. - - Returns: - bool: True iff client_universe matches the universe in credentials. - - Raises: - ValueError: when client_universe does not match the universe in credentials. - """ - - default_universe = QuotaServiceClient._DEFAULT_UNIVERSE - credentials_universe = getattr(credentials, "universe_domain", default_universe) - - if client_universe != credentials_universe: - raise ValueError("The configured universe domain " - f"({client_universe}) does not match the universe domain " - f"found in the credentials ({credentials_universe}). " - "If you haven't configured the universe domain explicitly, " - f"`{default_universe}` is the default.") - return True - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - self._is_universe_domain_valid = (self._is_universe_domain_valid or - QuotaServiceClient._compare_universes(self.universe_domain, self.transport._credentials)) - return self._is_universe_domain_valid - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[Union[str, QuotaServiceTransport, Callable[..., QuotaServiceTransport]]] = None, - client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the quota 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 (Optional[Union[str,QuotaServiceTransport,Callable[..., QuotaServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the QuotaServiceTransport constructor. - 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. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "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). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS 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. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - 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. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict(self._client_options) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast(client_options_lib.ClientOptions, self._client_options) - - universe_domain_opt = getattr(self._client_options, 'universe_domain', None) - - self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = QuotaServiceClient._read_environment_variables() - self._client_cert_source = QuotaServiceClient._get_client_cert_source(self._client_options.client_cert_source, self._use_client_cert) - self._universe_domain = QuotaServiceClient._get_universe_domain(universe_domain_opt, self._universe_domain_env) - self._api_endpoint = None # updated below, depending on `transport` - - # Initialize the universe domain validation. - self._is_universe_domain_valid = False - - api_key_value = getattr(self._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. - transport_provided = isinstance(transport, QuotaServiceTransport) - if transport_provided: - # transport is a QuotaServiceTransport instance. - if credentials or self._client_options.credentials_file or api_key_value: - raise ValueError("When providing a transport instance, " - "provide its credentials directly.") - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(QuotaServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = (self._api_endpoint or - QuotaServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint)) - - if not transport_provided: - 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_init: Union[Type[QuotaServiceTransport], Callable[..., QuotaServiceTransport]] = ( - QuotaServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., QuotaServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - api_audience=self._client_options.api_audience, - ) - - def list_quota_groups(self, - request: Optional[Union[quota.ListQuotaGroupsRequest, 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.ListQuotaGroupsPager: - r"""Lists the daily call quota and usage per group for - your Merchant Center account. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.shopping import merchant_quota_v1beta - - def sample_list_quota_groups(): - # Create a client - client = merchant_quota_v1beta.QuotaServiceClient() - - # Initialize request argument(s) - request = merchant_quota_v1beta.ListQuotaGroupsRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_quota_groups(request=request) - - # Handle the response - for response in page_result: - print(response) - - Args: - request (Union[google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsRequest, dict]): - The request object. Request message for the - ListQuotaGroups method. - parent (str): - Required. The merchant account who - owns the collection of method quotas - Format: accounts/{account} - - 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.shopping.merchant_quota_v1beta.services.quota_service.pagers.ListQuotaGroupsPager: - Response message for the - ListMethodGroups 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.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, quota.ListQuotaGroupsRequest): - request = quota.ListQuotaGroupsRequest(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_quota_groups] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # 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.ListQuotaGroupsPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "QuotaServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - - - - - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) - - -__all__ = ( - "QuotaServiceClient", -) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/pagers.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/pagers.py deleted file mode 100644 index 6b1ff68f444d..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/pagers.py +++ /dev/null @@ -1,162 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import retry_async as retries_async -from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator, Union -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] - OptionalAsyncRetry = Union[retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore - -from google.shopping.merchant_quota_v1beta.types import quota - - -class ListQuotaGroupsPager: - """A pager for iterating through ``list_quota_groups`` requests. - - This class thinly wraps an initial - :class:`google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsResponse` object, and - provides an ``__iter__`` method to iterate through its - ``quota_groups`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``ListQuotaGroups`` requests and continue to iterate - through the ``quota_groups`` field on the - corresponding responses. - - All the usual :class:`google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsResponse` - 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[..., quota.ListQuotaGroupsResponse], - request: quota.ListQuotaGroupsRequest, - response: quota.ListQuotaGroupsResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsRequest): - The initial request object. - response (google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = quota.ListQuotaGroupsRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[quota.ListQuotaGroupsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method(self._request, retry=self._retry, timeout=self._timeout, metadata=self._metadata) - yield self._response - - def __iter__(self) -> Iterator[quota.QuotaGroup]: - for page in self.pages: - yield from page.quota_groups - - def __repr__(self) -> str: - return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) - - -class ListQuotaGroupsAsyncPager: - """A pager for iterating through ``list_quota_groups`` requests. - - This class thinly wraps an initial - :class:`google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``quota_groups`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``ListQuotaGroups`` requests and continue to iterate - through the ``quota_groups`` field on the - corresponding responses. - - All the usual :class:`google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsResponse` - 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[quota.ListQuotaGroupsResponse]], - request: quota.ListQuotaGroupsRequest, - response: quota.ListQuotaGroupsResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsRequest): - The initial request object. - response (google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsResponse): - The initial response object. - retry (google.api_core.retry.AsyncRetry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = quota.ListQuotaGroupsRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages(self) -> AsyncIterator[quota.ListQuotaGroupsResponse]: - 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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) - yield self._response - def __aiter__(self) -> AsyncIterator[quota.QuotaGroup]: - async def async_generator(): - async for page in self.pages: - for response in page.quota_groups: - 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/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/README.rst b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/README.rst deleted file mode 100644 index 06b6eb4da828..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/README.rst +++ /dev/null @@ -1,9 +0,0 @@ - -transport inheritance structure -_______________________________ - -`QuotaServiceTransport` is the ABC for all transports. -- public child `QuotaServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). -- public child `QuotaServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). -- private child `_BaseQuotaServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). -- public child `QuotaServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/__init__.py deleted file mode 100644 index 1dddb73e2611..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/__init__.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 QuotaServiceTransport -from .grpc import QuotaServiceGrpcTransport -from .grpc_asyncio import QuotaServiceGrpcAsyncIOTransport -from .rest import QuotaServiceRestTransport -from .rest import QuotaServiceRestInterceptor - - -# Compile a registry of transports. -_transport_registry = OrderedDict() # type: Dict[str, Type[QuotaServiceTransport]] -_transport_registry['grpc'] = QuotaServiceGrpcTransport -_transport_registry['grpc_asyncio'] = QuotaServiceGrpcAsyncIOTransport -_transport_registry['rest'] = QuotaServiceRestTransport - -__all__ = ( - 'QuotaServiceTransport', - 'QuotaServiceGrpcTransport', - 'QuotaServiceGrpcAsyncIOTransport', - 'QuotaServiceRestTransport', - 'QuotaServiceRestInterceptor', -) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/base.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/base.py deleted file mode 100644 index b4e3103cc44f..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/base.py +++ /dev/null @@ -1,154 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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.shopping.merchant_quota_v1beta 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.shopping.merchant_quota_v1beta.types import quota - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) - - -class QuotaServiceTransport(abc.ABC): - """Abstract transport class for QuotaService.""" - - AUTH_SCOPES = ( - 'https://www.googleapis.com/auth/content', - ) - - DEFAULT_HOST: str = 'merchantapi.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 (default: 'merchantapi.googleapis.com'). - 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 not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # 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 and not self._ignore_credentials: - 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 - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.list_quota_groups: gapic_v1.method.wrap_method( - self.list_quota_groups, - 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_quota_groups(self) -> Callable[ - [quota.ListQuotaGroupsRequest], - Union[ - quota.ListQuotaGroupsResponse, - Awaitable[quota.ListQuotaGroupsResponse] - ]]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ( - 'QuotaServiceTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc.py deleted file mode 100644 index c052051bf10f..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc.py +++ /dev/null @@ -1,272 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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.shopping.merchant_quota_v1beta.types import quota -from .base import QuotaServiceTransport, DEFAULT_CLIENT_INFO - - -class QuotaServiceGrpcTransport(QuotaServiceTransport): - """gRPC backend transport for QuotaService. - - Service to get method call quota information per Merchant API - method. - - 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 = 'merchantapi.googleapis.com', - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[grpc.Channel, Callable[..., 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 (default: 'merchantapi.googleapis.com'). - 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 a ``channel`` instance 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 a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # 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: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - 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 = 'merchantapi.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_quota_groups(self) -> Callable[ - [quota.ListQuotaGroupsRequest], - quota.ListQuotaGroupsResponse]: - r"""Return a callable for the list quota groups method over gRPC. - - Lists the daily call quota and usage per group for - your Merchant Center account. - - Returns: - Callable[[~.ListQuotaGroupsRequest], - ~.ListQuotaGroupsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_quota_groups' not in self._stubs: - self._stubs['list_quota_groups'] = self.grpc_channel.unary_unary( - '/google.shopping.merchant.quota.v1beta.QuotaService/ListQuotaGroups', - request_serializer=quota.ListQuotaGroupsRequest.serialize, - response_deserializer=quota.ListQuotaGroupsResponse.deserialize, - ) - return self._stubs['list_quota_groups'] - - def close(self): - self.grpc_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ( - 'QuotaServiceGrpcTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py deleted file mode 100644 index 9ca22a02ebce..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,293 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 inspect -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 exceptions as core_exceptions -from google.api_core import retry_async as retries -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.shopping.merchant_quota_v1beta.types import quota -from .base import QuotaServiceTransport, DEFAULT_CLIENT_INFO -from .grpc import QuotaServiceGrpcTransport - - -class QuotaServiceGrpcAsyncIOTransport(QuotaServiceTransport): - """gRPC AsyncIO backend transport for QuotaService. - - Service to get method call quota information per Merchant API - method. - - 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 = 'merchantapi.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`. - 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 = 'merchantapi.googleapis.com', - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[aio.Channel, Callable[..., 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 (default: 'merchantapi.googleapis.com'). - 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 a ``channel`` instance 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 a ``channel`` instance 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[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # 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: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - 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._wrap_with_kind = "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters - 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_quota_groups(self) -> Callable[ - [quota.ListQuotaGroupsRequest], - Awaitable[quota.ListQuotaGroupsResponse]]: - r"""Return a callable for the list quota groups method over gRPC. - - Lists the daily call quota and usage per group for - your Merchant Center account. - - Returns: - Callable[[~.ListQuotaGroupsRequest], - Awaitable[~.ListQuotaGroupsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_quota_groups' not in self._stubs: - self._stubs['list_quota_groups'] = self.grpc_channel.unary_unary( - '/google.shopping.merchant.quota.v1beta.QuotaService/ListQuotaGroups', - request_serializer=quota.ListQuotaGroupsRequest.serialize, - response_deserializer=quota.ListQuotaGroupsResponse.deserialize, - ) - return self._stubs['list_quota_groups'] - - def _prep_wrapped_messages(self, client_info): - """ Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.list_quota_groups: self._wrap_method( - self.list_quota_groups, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self.grpc_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ( - 'QuotaServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py deleted file mode 100644 index bd44e7b6b0a0..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py +++ /dev/null @@ -1,276 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 -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 gapic_v1 - -from google.protobuf import json_format - -from requests import __version__ as requests_version -import dataclasses -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union -import warnings - - -from google.shopping.merchant_quota_v1beta.types import quota - - -from .rest_base import _BaseQuotaServiceRestTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, - grpc_version=None, - rest_version=f"requests@{requests_version}", -) - - -class QuotaServiceRestInterceptor: - """Interceptor for QuotaService. - - 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 QuotaServiceRestTransport. - - .. code-block:: python - class MyCustomQuotaServiceInterceptor(QuotaServiceRestInterceptor): - def pre_list_quota_groups(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_list_quota_groups(self, response): - logging.log(f"Received response: {response}") - return response - - transport = QuotaServiceRestTransport(interceptor=MyCustomQuotaServiceInterceptor()) - client = QuotaServiceClient(transport=transport) - - - """ - def pre_list_quota_groups(self, request: quota.ListQuotaGroupsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[quota.ListQuotaGroupsRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for list_quota_groups - - Override in a subclass to manipulate the request or metadata - before they are sent to the QuotaService server. - """ - return request, metadata - - def post_list_quota_groups(self, response: quota.ListQuotaGroupsResponse) -> quota.ListQuotaGroupsResponse: - """Post-rpc interceptor for list_quota_groups - - Override in a subclass to manipulate the response - after it is returned by the QuotaService server but before - it is returned to user code. - """ - return response - - -@dataclasses.dataclass -class QuotaServiceRestStub: - _session: AuthorizedSession - _host: str - _interceptor: QuotaServiceRestInterceptor - - -class QuotaServiceRestTransport(_BaseQuotaServiceRestTransport): - """REST backend synchronous transport for QuotaService. - - Service to get method call quota information per Merchant API - method. - - 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 = 'merchantapi.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[QuotaServiceRestInterceptor] = None, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'merchantapi.googleapis.com'). - 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 - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - url_scheme=url_scheme, - 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 QuotaServiceRestInterceptor() - self._prep_wrapped_messages(client_info) - - class _ListQuotaGroups(_BaseQuotaServiceRestTransport._BaseListQuotaGroups, QuotaServiceRestStub): - def __hash__(self): - return hash("QuotaServiceRestTransport.ListQuotaGroups") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__(self, - request: quota.ListQuotaGroupsRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> quota.ListQuotaGroupsResponse: - r"""Call the list quota groups method over HTTP. - - Args: - request (~.quota.ListQuotaGroupsRequest): - The request object. Request message for the - ListQuotaGroups method. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.quota.ListQuotaGroupsResponse: - Response message for the - ListMethodGroups method. - - """ - - http_options = _BaseQuotaServiceRestTransport._BaseListQuotaGroups._get_http_options() - request, metadata = self._interceptor.pre_list_quota_groups(request, metadata) - transcoded_request = _BaseQuotaServiceRestTransport._BaseListQuotaGroups._get_transcoded_request(http_options, request) - - # Jsonify the query params - query_params = _BaseQuotaServiceRestTransport._BaseListQuotaGroups._get_query_params_json(transcoded_request) - - # Send the request - response = QuotaServiceRestTransport._ListQuotaGroups._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) - - # 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 = quota.ListQuotaGroupsResponse() - pb_resp = quota.ListQuotaGroupsResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_quota_groups(resp) - return resp - - @property - def list_quota_groups(self) -> Callable[ - [quota.ListQuotaGroupsRequest], - quota.ListQuotaGroupsResponse]: - # 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._ListQuotaGroups(self._session, self._host, self._interceptor) # type: ignore - - @property - def kind(self) -> str: - return "rest" - - def close(self): - self._session.close() - - -__all__=( - 'QuotaServiceRestTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest_base.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest_base.py deleted file mode 100644 index c7b406f9d383..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest_base.py +++ /dev/null @@ -1,128 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 json # type: ignore -from google.api_core import path_template -from google.api_core import gapic_v1 - -from google.protobuf import json_format -from .base import QuotaServiceTransport, DEFAULT_CLIENT_INFO - -import re -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union - - -from google.shopping.merchant_quota_v1beta.types import quota - - -class _BaseQuotaServiceRestTransport(QuotaServiceTransport): - """Base REST backend transport for QuotaService. - - Note: This class is not meant to be used directly. Use its sync and - async sub-classes instead. - - 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 = 'merchantapi.googleapis.com', - credentials: Optional[Any] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - url_scheme: str = 'https', - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - Args: - host (Optional[str]): - The hostname to connect to (default: 'merchantapi.googleapis.com'). - credentials (Optional[Any]): 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. - 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 - 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 - ) - - class _BaseListQuotaGroups: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'get', - 'uri': '/quota/v1beta/{parent=accounts/*}/quotas', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = quota.ListQuotaGroupsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseQuotaServiceRestTransport._BaseListQuotaGroups._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - -__all__=( - '_BaseQuotaServiceRestTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/__init__.py deleted file mode 100644 index e4e09c52c9f5..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/__init__.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .quota import ( - ListQuotaGroupsRequest, - ListQuotaGroupsResponse, - MethodDetails, - QuotaGroup, -) - -__all__ = ( - 'ListQuotaGroupsRequest', - 'ListQuotaGroupsResponse', - 'MethodDetails', - 'QuotaGroup', -) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/quota.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/quota.py deleted file mode 100644 index c1a3a79456e3..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/google/shopping/merchant_quota_v1beta/types/quota.py +++ /dev/null @@ -1,184 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.shopping.merchant.quota.v1beta', - manifest={ - 'QuotaGroup', - 'MethodDetails', - 'ListQuotaGroupsRequest', - 'ListQuotaGroupsResponse', - }, -) - - -class QuotaGroup(proto.Message): - r"""The group information for methods in the Merchant API. The - quota is shared between all methods in the group. Even if none - of the methods within the group have usage the information for - the group is returned. - - Attributes: - name (str): - Identifier. The resource name of the quota - group. Format: accounts/{account}/quotas/{group} - Note: There is no guarantee on the format of - {group} - quota_usage (int): - Output only. The current quota usage, meaning - the number of calls already made on a given day - to the methods in the group. The daily quota - limits reset at at 12:00 PM midday UTC. - quota_limit (int): - Output only. The maximum number of calls - allowed per day for the group. - quota_minute_limit (int): - Output only. The maximum number of calls - allowed per minute for the group. - method_details (MutableSequence[google.shopping.merchant_quota_v1beta.types.MethodDetails]): - Output only. List of all methods group quota - applies to. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - quota_usage: int = proto.Field( - proto.INT64, - number=2, - ) - quota_limit: int = proto.Field( - proto.INT64, - number=3, - ) - quota_minute_limit: int = proto.Field( - proto.INT64, - number=5, - ) - method_details: MutableSequence['MethodDetails'] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message='MethodDetails', - ) - - -class MethodDetails(proto.Message): - r"""The method details per method in the Merchant API. - - Attributes: - method (str): - Output only. The name of the method for example - ``products.list``. - version (str): - Output only. The API version that the method - belongs to. - subapi (str): - Output only. The sub-API that the method - belongs to. - path (str): - Output only. The path for the method such as - ``products/v1/productInputs.insert`` - """ - - method: str = proto.Field( - proto.STRING, - number=1, - ) - version: str = proto.Field( - proto.STRING, - number=2, - ) - subapi: str = proto.Field( - proto.STRING, - number=3, - ) - path: str = proto.Field( - proto.STRING, - number=4, - ) - - -class ListQuotaGroupsRequest(proto.Message): - r"""Request message for the ListQuotaGroups method. - - Attributes: - parent (str): - Required. The merchant account who owns the - collection of method quotas Format: - accounts/{account} - page_size (int): - Optional. The maximum number of quotas to - return in the response, used for paging. - Defaults to 500; values above 1000 will be - coerced to 1000. - page_token (str): - Optional. Token (if provided) to retrieve the - subsequent page. All other parameters must match - the original call that provided the page token. - """ - - 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 ListQuotaGroupsResponse(proto.Message): - r"""Response message for the ListMethodGroups method. - - Attributes: - quota_groups (MutableSequence[google.shopping.merchant_quota_v1beta.types.QuotaGroup]): - The methods, current quota usage and limits per each group. - The quota is shared between all methods in the group. The - groups are sorted in descending order based on - [quotaUsage][google.shopping.merchant.quota.v1main.QuotaGroup.quota_usage]. - next_page_token (str): - A token, which can be sent as ``page_token`` to retrieve the - next page. If this field is omitted, there are no subsequent - pages. - """ - - @property - def raw_page(self): - return self - - quota_groups: MutableSequence['QuotaGroup'] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message='QuotaGroup', - ) - next_page_token: str = proto.Field( - proto.STRING, - number=2, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/mypy.ini b/owl-bot-staging/google-shopping-merchant-quota/v1beta/mypy.ini deleted file mode 100644 index 574c5aed394b..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/mypy.ini +++ /dev/null @@ -1,3 +0,0 @@ -[mypy] -python_version = 3.7 -namespace_packages = True diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/noxfile.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/noxfile.py deleted file mode 100644 index ab60f2f71caf..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/noxfile.py +++ /dev/null @@ -1,280 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 re -import shutil -import subprocess -import sys - - -import nox # type: ignore - -ALL_PYTHON = [ - "3.7", - "3.8", - "3.9", - "3.10", - "3.11", - "3.12", - "3.13", -] - -CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() - -LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" -PACKAGE_NAME = 'google-shopping-merchant-quota' - -BLACK_VERSION = "black==22.3.0" -BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] -DEFAULT_PYTHON_VERSION = "3.13" - -nox.sessions = [ - "unit", - "cover", - "mypy", - "check_lower_bounds" - # exclude update_lower_bounds from default - "docs", - "blacken", - "lint", - "prerelease_deps", -] - -@nox.session(python=ALL_PYTHON) -@nox.parametrize( - "protobuf_implementation", - [ "python", "upb", "cpp" ], -) -def unit(session, protobuf_implementation): - """Run the unit test suite.""" - - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): - session.skip("cpp implementation is not supported in python 3.11+") - - session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') - session.install('-e', '.', "-c", f"testing/constraints-{session.python}.txt") - - # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. - # The 'cpp' implementation requires Protobuf<4. - if protobuf_implementation == "cpp": - session.install("protobuf<4") - - session.run( - 'py.test', - '--quiet', - '--cov=google/shopping/merchant_quota_v1beta/', - '--cov=tests/', - '--cov-config=.coveragerc', - '--cov-report=term', - '--cov-report=html', - os.path.join('tests', 'unit', ''.join(session.posargs)), - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - -@nox.session(python=ALL_PYTHON[-1]) -@nox.parametrize( - "protobuf_implementation", - [ "python", "upb", "cpp" ], -) -def prerelease_deps(session, protobuf_implementation): - """Run the unit test suite against pre-release versions of dependencies.""" - - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): - session.skip("cpp implementation is not supported in python 3.11+") - - # Install test environment dependencies - session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') - - # Install the package without dependencies - session.install('-e', '.', '--no-deps') - - # We test the minimum dependency versions using the minimum Python - # version so the lowest python runtime that we test has a corresponding constraints - # file, located at `testing/constraints--.txt`, which contains all of the - # dependencies and extras. - with open( - CURRENT_DIRECTORY - / "testing" - / f"constraints-{ALL_PYTHON[0]}.txt", - encoding="utf-8", - ) as constraints_file: - constraints_text = constraints_file.read() - - # Ignore leading whitespace and comment lines. - constraints_deps = [ - match.group(1) - for match in re.finditer( - r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE - ) - ] - - session.install(*constraints_deps) - - prerel_deps = [ - "googleapis-common-protos", - "google-api-core", - "google-auth", - # Exclude grpcio!=1.67.0rc1 which does not support python 3.13 - "grpcio!=1.67.0rc1", - "grpcio-status", - "protobuf", - "proto-plus", - ] - - for dep in prerel_deps: - session.install("--pre", "--no-deps", "--upgrade", dep) - - # Remaining dependencies - other_deps = [ - "requests", - ] - session.install(*other_deps) - - # Print out prerelease package versions - - session.run("python", "-c", "import google.api_core; print(google.api_core.__version__)") - session.run("python", "-c", "import google.auth; print(google.auth.__version__)") - session.run("python", "-c", "import grpc; print(grpc.__version__)") - session.run( - "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" - ) - session.run( - "python", "-c", "import proto; print(proto.__version__)" - ) - - session.run( - 'py.test', - '--quiet', - '--cov=google/shopping/merchant_quota_v1beta/', - '--cov=tests/', - '--cov-config=.coveragerc', - '--cov-report=term', - '--cov-report=html', - os.path.join('tests', 'unit', ''.join(session.posargs)), - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - - -@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', - '-p', - '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, - ) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_async.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_async.py deleted file mode 100644 index 9df3fdc41d00..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_async.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListQuotaGroups -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-shopping-merchant-quota - - -# [START merchantapi_v1beta_generated_QuotaService_ListQuotaGroups_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.shopping import merchant_quota_v1beta - - -async def sample_list_quota_groups(): - # Create a client - client = merchant_quota_v1beta.QuotaServiceAsyncClient() - - # Initialize request argument(s) - request = merchant_quota_v1beta.ListQuotaGroupsRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_quota_groups(request=request) - - # Handle the response - async for response in page_result: - print(response) - -# [END merchantapi_v1beta_generated_QuotaService_ListQuotaGroups_async] diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_sync.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_sync.py deleted file mode 100644 index 9cb0fe36a759..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/merchantapi_v1beta_generated_quota_service_list_quota_groups_sync.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListQuotaGroups -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-shopping-merchant-quota - - -# [START merchantapi_v1beta_generated_QuotaService_ListQuotaGroups_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.shopping import merchant_quota_v1beta - - -def sample_list_quota_groups(): - # Create a client - client = merchant_quota_v1beta.QuotaServiceClient() - - # Initialize request argument(s) - request = merchant_quota_v1beta.ListQuotaGroupsRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_quota_groups(request=request) - - # Handle the response - for response in page_result: - print(response) - -# [END merchantapi_v1beta_generated_QuotaService_ListQuotaGroups_sync] diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1beta.json b/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1beta.json deleted file mode 100644 index 884c8d108671..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.quota.v1beta.json +++ /dev/null @@ -1,176 +0,0 @@ -{ - "clientLibrary": { - "apis": [ - { - "id": "google.shopping.merchant.quota.v1beta", - "version": "v1beta" - } - ], - "language": "PYTHON", - "name": "google-shopping-merchant-quota", - "version": "0.1.0" - }, - "snippets": [ - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.shopping.merchant_quota_v1beta.QuotaServiceAsyncClient", - "shortName": "QuotaServiceAsyncClient" - }, - "fullName": "google.shopping.merchant_quota_v1beta.QuotaServiceAsyncClient.list_quota_groups", - "method": { - "fullName": "google.shopping.merchant.quota.v1beta.QuotaService.ListQuotaGroups", - "service": { - "fullName": "google.shopping.merchant.quota.v1beta.QuotaService", - "shortName": "QuotaService" - }, - "shortName": "ListQuotaGroups" - }, - "parameters": [ - { - "name": "request", - "type": "google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsRequest" - }, - { - "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.shopping.merchant_quota_v1beta.services.quota_service.pagers.ListQuotaGroupsAsyncPager", - "shortName": "list_quota_groups" - }, - "description": "Sample for ListQuotaGroups", - "file": "merchantapi_v1beta_generated_quota_service_list_quota_groups_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "merchantapi_v1beta_generated_QuotaService_ListQuotaGroups_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": "merchantapi_v1beta_generated_quota_service_list_quota_groups_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.shopping.merchant_quota_v1beta.QuotaServiceClient", - "shortName": "QuotaServiceClient" - }, - "fullName": "google.shopping.merchant_quota_v1beta.QuotaServiceClient.list_quota_groups", - "method": { - "fullName": "google.shopping.merchant.quota.v1beta.QuotaService.ListQuotaGroups", - "service": { - "fullName": "google.shopping.merchant.quota.v1beta.QuotaService", - "shortName": "QuotaService" - }, - "shortName": "ListQuotaGroups" - }, - "parameters": [ - { - "name": "request", - "type": "google.shopping.merchant_quota_v1beta.types.ListQuotaGroupsRequest" - }, - { - "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.shopping.merchant_quota_v1beta.services.quota_service.pagers.ListQuotaGroupsPager", - "shortName": "list_quota_groups" - }, - "description": "Sample for ListQuotaGroups", - "file": "merchantapi_v1beta_generated_quota_service_list_quota_groups_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "merchantapi_v1beta_generated_QuotaService_ListQuotaGroups_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": "merchantapi_v1beta_generated_quota_service_list_quota_groups_sync.py" - } - ] -} diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/scripts/fixup_merchant_quota_v1beta_keywords.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/scripts/fixup_merchant_quota_v1beta_keywords.py deleted file mode 100644 index 46854d66644a..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/scripts/fixup_merchant_quota_v1beta_keywords.py +++ /dev/null @@ -1,176 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 merchant_quotaCallTransformer(cst.CSTTransformer): - CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') - METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { - 'list_quota_groups': ('parent', 'page_size', 'page_token', ), - } - - 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=merchant_quotaCallTransformer(), -): - """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 merchant_quota 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/google-shopping-merchant-quota/v1beta/setup.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/setup.py deleted file mode 100644 index 29c7175c3c3a..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/setup.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 re - -import setuptools # type: ignore - -package_root = os.path.abspath(os.path.dirname(__file__)) - -name = 'google-shopping-merchant-quota' - - -description = "Google Shopping Merchant Quota API client library" - -version = None - -with open(os.path.join(package_root, 'google/shopping/merchant_quota/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) - assert (len(version_candidates) == 1) - version = version_candidates[0] - -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.1, <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.*", - # Exclude incompatible versions of `google-auth` - # See https://github.com/googleapis/google-cloud-python/issues/12364 - "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", - "proto-plus >= 1.22.3, <2.0.0dev", - "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", - "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", -] -extras = { -} -url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-quota" - -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.find_namespace_packages() - if package.startswith("google") -] - -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", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Operating System :: OS Independent", - "Topic :: Internet", - ], - platforms="Posix; MacOS X; Windows", - packages=packages, - python_requires=">=3.7", - install_requires=dependencies, - extras_require=extras, - include_package_data=True, - zip_safe=False, -) diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.10.txt b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.10.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.10.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/google-shopping-merchant-quota/v1beta/testing/constraints-3.11.txt b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.11.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.11.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/google-shopping-merchant-quota/v1beta/testing/constraints-3.12.txt b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.12.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.12.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/google-shopping-merchant-quota/v1beta/testing/constraints-3.7.txt b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.7.txt deleted file mode 100644 index fc812592b0ee..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.7.txt +++ /dev/null @@ -1,10 +0,0 @@ -# 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.1 -google-auth==2.14.1 -proto-plus==1.22.3 -protobuf==3.20.2 diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.8.txt b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.8.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.8.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/google-shopping-merchant-quota/v1beta/testing/constraints-3.9.txt b/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.9.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.9.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/google-shopping-merchant-quota/v1beta/tests/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-quota/v1beta/tests/unit/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-quota/v1beta/tests/unit/gapic/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/__init__.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py b/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py deleted file mode 100644 index e7c65aed459a..000000000000 --- a/owl-bot-staging/google-shopping-merchant-quota/v1beta/tests/unit/gapic/merchant_quota_v1beta/test_quota_service.py +++ /dev/null @@ -1,2403 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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, AsyncIterable -from google.protobuf import json_format -import json -import math -import pytest -from google.api_core import api_core_version -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 - -try: - from google.auth.aio import credentials as ga_credentials_async - HAS_GOOGLE_AUTH_AIO = True -except ImportError: # pragma: NO COVER - HAS_GOOGLE_AUTH_AIO = False - -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.api_core import retry as retries -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account -from google.shopping.merchant_quota_v1beta.services.quota_service import QuotaServiceAsyncClient -from google.shopping.merchant_quota_v1beta.services.quota_service import QuotaServiceClient -from google.shopping.merchant_quota_v1beta.services.quota_service import pagers -from google.shopping.merchant_quota_v1beta.services.quota_service import transports -from google.shopping.merchant_quota_v1beta.types import quota -import google.auth - - -async def mock_async_gen(data, chunk_size=1): - for i in range(0, len(data)): # pragma: NO COVER - chunk = data[i : i + chunk_size] - yield chunk.encode("utf-8") - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - -# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. -# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. -def async_anonymous_credentials(): - if HAS_GOOGLE_AUTH_AIO: - return ga_credentials_async.AnonymousCredentials() - return ga_credentials.AnonymousCredentials() - -# 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 - -# If default endpoint template is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint template so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint_template(client): - return "test.{UNIVERSE_DOMAIN}" if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) else client._DEFAULT_ENDPOINT_TEMPLATE - - -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 QuotaServiceClient._get_default_mtls_endpoint(None) is None - assert QuotaServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint - assert QuotaServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint - assert QuotaServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint - assert QuotaServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint - assert QuotaServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - -def test__read_environment_variables(): - assert QuotaServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert QuotaServiceClient._read_environment_variables() == (True, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - assert QuotaServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError) as excinfo: - QuotaServiceClient._read_environment_variables() - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - assert QuotaServiceClient._read_environment_variables() == (False, "never", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - assert QuotaServiceClient._read_environment_variables() == (False, "always", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): - assert QuotaServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - QuotaServiceClient._read_environment_variables() - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): - assert QuotaServiceClient._read_environment_variables() == (False, "auto", "foo.com") - -def test__get_client_cert_source(): - mock_provided_cert_source = mock.Mock() - mock_default_cert_source = mock.Mock() - - assert QuotaServiceClient._get_client_cert_source(None, False) is None - assert QuotaServiceClient._get_client_cert_source(mock_provided_cert_source, False) is None - assert QuotaServiceClient._get_client_cert_source(mock_provided_cert_source, True) == mock_provided_cert_source - - 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_default_cert_source): - assert QuotaServiceClient._get_client_cert_source(None, True) is mock_default_cert_source - assert QuotaServiceClient._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source - -@mock.patch.object(QuotaServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceClient)) -@mock.patch.object(QuotaServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceAsyncClient)) -def test__get_api_endpoint(): - api_override = "foo.com" - mock_client_cert_source = mock.Mock() - default_universe = QuotaServiceClient._DEFAULT_UNIVERSE - default_endpoint = QuotaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) - mock_universe = "bar.com" - mock_endpoint = QuotaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) - - assert QuotaServiceClient._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override - assert QuotaServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == QuotaServiceClient.DEFAULT_MTLS_ENDPOINT - assert QuotaServiceClient._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint - assert QuotaServiceClient._get_api_endpoint(None, None, default_universe, "always") == QuotaServiceClient.DEFAULT_MTLS_ENDPOINT - assert QuotaServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == QuotaServiceClient.DEFAULT_MTLS_ENDPOINT - assert QuotaServiceClient._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint - assert QuotaServiceClient._get_api_endpoint(None, None, default_universe, "never") == default_endpoint - - with pytest.raises(MutualTLSChannelError) as excinfo: - QuotaServiceClient._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto") - assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com." - - -def test__get_universe_domain(): - client_universe_domain = "foo.com" - universe_domain_env = "bar.com" - - assert QuotaServiceClient._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain - assert QuotaServiceClient._get_universe_domain(None, universe_domain_env) == universe_domain_env - assert QuotaServiceClient._get_universe_domain(None, None) == QuotaServiceClient._DEFAULT_UNIVERSE - - with pytest.raises(ValueError) as excinfo: - QuotaServiceClient._get_universe_domain("", None) - assert str(excinfo.value) == "Universe Domain cannot be an empty string." - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc"), - (QuotaServiceClient, transports.QuotaServiceRestTransport, "rest"), -]) -def test__validate_universe_domain(client_class, transport_class, transport_name): - client = client_class( - transport=transport_class( - credentials=ga_credentials.AnonymousCredentials() - ) - ) - assert client._validate_universe_domain() == True - - # Test the case when universe is already validated. - assert client._validate_universe_domain() == True - - if transport_name == "grpc": - # Test the case where credentials are provided by the - # `local_channel_credentials`. The default universes in both match. - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - client = client_class(transport=transport_class(channel=channel)) - assert client._validate_universe_domain() == True - - # Test the case where credentials do not exist: e.g. a transport is provided - # with no credentials. Validation should still succeed because there is no - # mismatch with non-existent credentials. - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - transport=transport_class(channel=channel) - transport._credentials = None - client = client_class(transport=transport) - assert client._validate_universe_domain() == True - - # TODO: This is needed to cater for older versions of google-auth - # Make this test unconditional once the minimum supported version of - # google-auth becomes 2.23.0 or higher. - google_auth_major, google_auth_minor = [int(part) for part in google.auth.__version__.split(".")[0:2]] - if google_auth_major > 2 or (google_auth_major == 2 and google_auth_minor >= 23): - credentials = ga_credentials.AnonymousCredentials() - credentials._universe_domain = "foo.com" - # Test the case when there is a universe mismatch from the credentials. - client = client_class( - transport=transport_class(credentials=credentials) - ) - with pytest.raises(ValueError) as excinfo: - client._validate_universe_domain() - assert str(excinfo.value) == "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (foo.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." - - # Test the case when there is a universe mismatch from the client. - # - # TODO: Make this test unconditional once the minimum supported version of - # google-api-core becomes 2.15.0 or higher. - api_core_major, api_core_minor = [int(part) for part in api_core_version.__version__.split(".")[0:2]] - if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 15): - client = client_class(client_options={"universe_domain": "bar.com"}, transport=transport_class(credentials=ga_credentials.AnonymousCredentials(),)) - with pytest.raises(ValueError) as excinfo: - client._validate_universe_domain() - assert str(excinfo.value) == "The configured universe domain (bar.com) does not match the universe domain found in the credentials (googleapis.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." - - # Test that ValueError is raised if universe_domain is provided via client options and credentials is None - with pytest.raises(ValueError): - client._compare_universes("foo.bar", None) - - -@pytest.mark.parametrize("client_class,transport_name", [ - (QuotaServiceClient, "grpc"), - (QuotaServiceAsyncClient, "grpc_asyncio"), - (QuotaServiceClient, "rest"), -]) -def test_quota_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 == ( - 'merchantapi.googleapis.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else - 'https://merchantapi.googleapis.com' - ) - - -@pytest.mark.parametrize("transport_class,transport_name", [ - (transports.QuotaServiceGrpcTransport, "grpc"), - (transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (transports.QuotaServiceRestTransport, "rest"), -]) -def test_quota_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", [ - (QuotaServiceClient, "grpc"), - (QuotaServiceAsyncClient, "grpc_asyncio"), - (QuotaServiceClient, "rest"), -]) -def test_quota_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 == ( - 'merchantapi.googleapis.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else - 'https://merchantapi.googleapis.com' - ) - - -def test_quota_service_client_get_transport_class(): - transport = QuotaServiceClient.get_transport_class() - available_transports = [ - transports.QuotaServiceGrpcTransport, - transports.QuotaServiceRestTransport, - ] - assert transport in available_transports - - transport = QuotaServiceClient.get_transport_class("grpc") - assert transport == transports.QuotaServiceGrpcTransport - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc"), - (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (QuotaServiceClient, transports.QuotaServiceRestTransport, "rest"), -]) -@mock.patch.object(QuotaServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceClient)) -@mock.patch.object(QuotaServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceAsyncClient)) -def test_quota_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(QuotaServiceClient, '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(QuotaServiceClient, '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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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) as excinfo: - client = client_class(transport=transport_name) - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - # 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) as excinfo: - client = client_class(transport=transport_name) - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - - # 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - 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", [ - (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc", "true"), - (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), - (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc", "false"), - (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), - (QuotaServiceClient, transports.QuotaServiceRestTransport, "rest", "true"), - (QuotaServiceClient, transports.QuotaServiceRestTransport, "rest", "false"), -]) -@mock.patch.object(QuotaServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceClient)) -@mock.patch.object(QuotaServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceAsyncClient)) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_quota_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) - 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) - 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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", [ - QuotaServiceClient, QuotaServiceAsyncClient -]) -@mock.patch.object(QuotaServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(QuotaServiceClient)) -@mock.patch.object(QuotaServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(QuotaServiceAsyncClient)) -def test_quota_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 - - # 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) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - # 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) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - -@pytest.mark.parametrize("client_class", [ - QuotaServiceClient, QuotaServiceAsyncClient -]) -@mock.patch.object(QuotaServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceClient)) -@mock.patch.object(QuotaServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(QuotaServiceAsyncClient)) -def test_quota_service_client_client_api_endpoint(client_class): - mock_client_cert_source = client_cert_source_callback - api_override = "foo.com" - default_universe = QuotaServiceClient._DEFAULT_UNIVERSE - default_endpoint = QuotaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) - mock_universe = "bar.com" - mock_endpoint = QuotaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) - - # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", - # use ClientOptions.api_endpoint as the api endpoint regardless. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel"): - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=api_override) - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == api_override - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", - # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - - # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), - # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, - # and ClientOptions.universe_domain="bar.com", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. - options = client_options.ClientOptions() - universe_exists = hasattr(options, "universe_domain") - if universe_exists: - options = client_options.ClientOptions(universe_domain=mock_universe) - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - else: - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == (mock_endpoint if universe_exists else default_endpoint) - assert client.universe_domain == (mock_universe if universe_exists else default_universe) - - # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - options = client_options.ClientOptions() - if hasattr(options, "universe_domain"): - delattr(options, "universe_domain") - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc"), - (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (QuotaServiceClient, transports.QuotaServiceRestTransport, "rest"), -]) -def test_quota_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - 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", [ - (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc", grpc_helpers), - (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), - (QuotaServiceClient, transports.QuotaServiceRestTransport, "rest", None), -]) -def test_quota_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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_quota_service_client_client_options_from_dict(): - with mock.patch('google.shopping.merchant_quota_v1beta.services.quota_service.transports.QuotaServiceGrpcTransport.__init__') as grpc_transport: - grpc_transport.return_value = None - client = QuotaServiceClient( - 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", [ - (QuotaServiceClient, transports.QuotaServiceGrpcTransport, "grpc", grpc_helpers), - (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), -]) -def test_quota_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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( - "merchantapi.googleapis.com:443", - credentials=file_creds, - credentials_file=None, - quota_project_id=None, - default_scopes=( - 'https://www.googleapis.com/auth/content', -), - scopes=None, - default_host="merchantapi.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("request_type", [ - quota.ListQuotaGroupsRequest, - dict, -]) -def test_list_quota_groups(request_type, transport: str = 'grpc'): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_quota_groups), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = quota.ListQuotaGroupsResponse( - next_page_token='next_page_token_value', - ) - response = client.list_quota_groups(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = quota.ListQuotaGroupsRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListQuotaGroupsPager) - assert response.next_page_token == 'next_page_token_value' - - -def test_list_quota_groups_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = quota.ListQuotaGroupsRequest( - parent='parent_value', - page_token='page_token_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_quota_groups), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.list_quota_groups(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == quota.ListQuotaGroupsRequest( - parent='parent_value', - page_token='page_token_value', - ) - -def test_list_quota_groups_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_quota_groups in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.list_quota_groups] = mock_rpc - request = {} - client.list_quota_groups(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_quota_groups(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_quota_groups_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = QuotaServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.list_quota_groups in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.list_quota_groups] = mock_rpc - - request = {} - await client.list_quota_groups(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.list_quota_groups(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_quota_groups_async(transport: str = 'grpc_asyncio', request_type=quota.ListQuotaGroupsRequest): - client = QuotaServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_quota_groups), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(quota.ListQuotaGroupsResponse( - next_page_token='next_page_token_value', - )) - response = await client.list_quota_groups(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = quota.ListQuotaGroupsRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListQuotaGroupsAsyncPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.asyncio -async def test_list_quota_groups_async_from_dict(): - await test_list_quota_groups_async(request_type=dict) - -def test_list_quota_groups_field_headers(): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = quota.ListQuotaGroupsRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_quota_groups), - '__call__') as call: - call.return_value = quota.ListQuotaGroupsResponse() - client.list_quota_groups(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_quota_groups_field_headers_async(): - client = QuotaServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = quota.ListQuotaGroupsRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_quota_groups), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(quota.ListQuotaGroupsResponse()) - await client.list_quota_groups(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_quota_groups_flattened(): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_quota_groups), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = quota.ListQuotaGroupsResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.list_quota_groups( - 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_quota_groups_flattened_error(): - client = QuotaServiceClient( - 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_quota_groups( - quota.ListQuotaGroupsRequest(), - parent='parent_value', - ) - -@pytest.mark.asyncio -async def test_list_quota_groups_flattened_async(): - client = QuotaServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_quota_groups), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = quota.ListQuotaGroupsResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(quota.ListQuotaGroupsResponse()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.list_quota_groups( - 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_quota_groups_flattened_error_async(): - client = QuotaServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.list_quota_groups( - quota.ListQuotaGroupsRequest(), - parent='parent_value', - ) - - -def test_list_quota_groups_pager(transport_name: str = "grpc"): - client = QuotaServiceClient( - 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_quota_groups), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - quota.QuotaGroup(), - quota.QuotaGroup(), - ], - next_page_token='abc', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[], - next_page_token='def', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - ], - next_page_token='ghi', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - quota.QuotaGroup(), - ], - ), - RuntimeError, - ) - - expected_metadata = () - retry = retries.Retry() - timeout = 5 - expected_metadata = tuple(expected_metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ('parent', ''), - )), - ) - pager = client.list_quota_groups(request={}, retry=retry, timeout=timeout) - - assert pager._metadata == expected_metadata - assert pager._retry == retry - assert pager._timeout == timeout - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, quota.QuotaGroup) - for i in results) -def test_list_quota_groups_pages(transport_name: str = "grpc"): - client = QuotaServiceClient( - 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_quota_groups), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - quota.QuotaGroup(), - quota.QuotaGroup(), - ], - next_page_token='abc', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[], - next_page_token='def', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - ], - next_page_token='ghi', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - quota.QuotaGroup(), - ], - ), - RuntimeError, - ) - pages = list(client.list_quota_groups(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_quota_groups_async_pager(): - client = QuotaServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_quota_groups), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - quota.QuotaGroup(), - quota.QuotaGroup(), - ], - next_page_token='abc', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[], - next_page_token='def', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - ], - next_page_token='ghi', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - quota.QuotaGroup(), - ], - ), - RuntimeError, - ) - async_pager = await client.list_quota_groups(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, quota.QuotaGroup) - for i in responses) - - -@pytest.mark.asyncio -async def test_list_quota_groups_async_pages(): - client = QuotaServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_quota_groups), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - quota.QuotaGroup(), - quota.QuotaGroup(), - ], - next_page_token='abc', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[], - next_page_token='def', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - ], - next_page_token='ghi', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - quota.QuotaGroup(), - ], - ), - 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_quota_groups(request={}) - ).pages: - pages.append(page_) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - - -def test_list_quota_groups_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_quota_groups in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.list_quota_groups] = mock_rpc - - request = {} - client.list_quota_groups(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_quota_groups(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_list_quota_groups_rest_required_fields(request_type=quota.ListQuotaGroupsRequest): - transport_class = transports.QuotaServiceRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_quota_groups._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_quota_groups._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 = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = quota.ListQuotaGroupsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "get", - 'query_params': pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = quota.ListQuotaGroupsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.list_quota_groups(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_list_quota_groups_rest_unset_required_fields(): - transport = transports.QuotaServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.list_quota_groups._get_unset_required_fields({}) - assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) - - -def test_list_quota_groups_rest_flattened(): - client = QuotaServiceClient( - 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 = quota.ListQuotaGroupsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {'parent': 'accounts/sample1'} - - # get truthy value for each flattened field - mock_args = dict( - parent='parent_value', - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = quota.ListQuotaGroupsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.list_quota_groups(**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/quota/v1beta/{parent=accounts/*}/quotas" % client.transport._host, args[1]) - - -def test_list_quota_groups_rest_flattened_error(transport: str = 'rest'): - client = QuotaServiceClient( - 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_quota_groups( - quota.ListQuotaGroupsRequest(), - parent='parent_value', - ) - - -def test_list_quota_groups_rest_pager(transport: str = 'rest'): - client = QuotaServiceClient( - 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 = ( - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - quota.QuotaGroup(), - quota.QuotaGroup(), - ], - next_page_token='abc', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[], - next_page_token='def', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - ], - next_page_token='ghi', - ), - quota.ListQuotaGroupsResponse( - quota_groups=[ - quota.QuotaGroup(), - quota.QuotaGroup(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(quota.ListQuotaGroupsResponse.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': 'accounts/sample1'} - - pager = client.list_quota_groups(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, quota.QuotaGroup) - for i in results) - - pages = list(client.list_quota_groups(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.QuotaServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.QuotaServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = QuotaServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.QuotaServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = QuotaServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = QuotaServiceClient( - client_options=options, - credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.QuotaServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = QuotaServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.QuotaServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = QuotaServiceClient(transport=transport) - assert client.transport is transport - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.QuotaServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.QuotaServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize("transport_class", [ - transports.QuotaServiceGrpcTransport, - transports.QuotaServiceGrpcAsyncIOTransport, - transports.QuotaServiceRestTransport, -]) -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() - -def test_transport_kind_grpc(): - transport = QuotaServiceClient.get_transport_class("grpc")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "grpc" - - -def test_initialize_client_w_grpc(): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_quota_groups_empty_call_grpc(): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_quota_groups), - '__call__') as call: - call.return_value = quota.ListQuotaGroupsResponse() - client.list_quota_groups(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = quota.ListQuotaGroupsRequest() - - assert args[0] == request_msg - - -def test_transport_kind_grpc_asyncio(): - transport = QuotaServiceAsyncClient.get_transport_class("grpc_asyncio")( - credentials=async_anonymous_credentials() - ) - assert transport.kind == "grpc_asyncio" - - -def test_initialize_client_w_grpc_asyncio(): - client = QuotaServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_quota_groups_empty_call_grpc_asyncio(): - client = QuotaServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_quota_groups), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(quota.ListQuotaGroupsResponse( - next_page_token='next_page_token_value', - )) - await client.list_quota_groups(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = quota.ListQuotaGroupsRequest() - - assert args[0] == request_msg - - -def test_transport_kind_rest(): - transport = QuotaServiceClient.get_transport_class("rest")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "rest" - - -def test_list_quota_groups_rest_bad_request(request_type=quota.ListQuotaGroupsRequest): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'parent': 'accounts/sample1'} - 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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.list_quota_groups(request) - - -@pytest.mark.parametrize("request_type", [ - quota.ListQuotaGroupsRequest, - dict, -]) -def test_list_quota_groups_rest_call_success(request_type): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'parent': 'accounts/sample1'} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), 'request') as req: - # Designate an appropriate value for the returned response. - return_value = quota.ListQuotaGroupsResponse( - next_page_token='next_page_token_value', - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = quota.ListQuotaGroupsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.list_quota_groups(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListQuotaGroupsPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_quota_groups_rest_interceptors(null_interceptor): - transport = transports.QuotaServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.QuotaServiceRestInterceptor(), - ) - client = QuotaServiceClient(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.QuotaServiceRestInterceptor, "post_list_quota_groups") as post, \ - mock.patch.object(transports.QuotaServiceRestInterceptor, "pre_list_quota_groups") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = quota.ListQuotaGroupsRequest.pb(quota.ListQuotaGroupsRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = quota.ListQuotaGroupsResponse.to_json(quota.ListQuotaGroupsResponse()) - req.return_value.content = return_value - - request = quota.ListQuotaGroupsRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = quota.ListQuotaGroupsResponse() - - client.list_quota_groups(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - -def test_initialize_client_w_rest(): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_quota_groups_empty_call_rest(): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_quota_groups), - '__call__') as call: - client.list_quota_groups(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = quota.ListQuotaGroupsRequest() - - assert args[0] == request_msg - - -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert isinstance( - client.transport, - transports.QuotaServiceGrpcTransport, - ) - -def test_quota_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.QuotaServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json" - ) - - -def test_quota_service_base_transport(): - # Instantiate the base transport. - with mock.patch('google.shopping.merchant_quota_v1beta.services.quota_service.transports.QuotaServiceTransport.__init__') as Transport: - Transport.return_value = None - transport = transports.QuotaServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - 'list_quota_groups', - ) - 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_quota_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.shopping.merchant_quota_v1beta.services.quota_service.transports.QuotaServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.QuotaServiceTransport( - 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/content', -), - quota_project_id="octopus", - ) - - -def test_quota_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.shopping.merchant_quota_v1beta.services.quota_service.transports.QuotaServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.QuotaServiceTransport() - adc.assert_called_once() - - -def test_quota_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) - QuotaServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/content', -), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.QuotaServiceGrpcTransport, - transports.QuotaServiceGrpcAsyncIOTransport, - ], -) -def test_quota_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/content',), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.QuotaServiceGrpcTransport, - transports.QuotaServiceGrpcAsyncIOTransport, - transports.QuotaServiceRestTransport, - ], -) -def test_quota_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.QuotaServiceGrpcTransport, grpc_helpers), - (transports.QuotaServiceGrpcAsyncIOTransport, grpc_helpers_async) - ], -) -def test_quota_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( - "merchantapi.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=( - 'https://www.googleapis.com/auth/content', -), - scopes=["1", "2"], - default_host="merchantapi.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("transport_class", [transports.QuotaServiceGrpcTransport, transports.QuotaServiceGrpcAsyncIOTransport]) -def test_quota_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_quota_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.QuotaServiceRestTransport ( - 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_quota_service_host_no_port(transport_name): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='merchantapi.googleapis.com'), - transport=transport_name, - ) - assert client.transport._host == ( - 'merchantapi.googleapis.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else 'https://merchantapi.googleapis.com' - ) - -@pytest.mark.parametrize("transport_name", [ - "grpc", - "grpc_asyncio", - "rest", -]) -def test_quota_service_host_with_port(transport_name): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='merchantapi.googleapis.com:8000'), - transport=transport_name, - ) - assert client.transport._host == ( - 'merchantapi.googleapis.com:8000' - if transport_name in ['grpc', 'grpc_asyncio'] - else 'https://merchantapi.googleapis.com:8000' - ) - -@pytest.mark.parametrize("transport_name", [ - "rest", -]) -def test_quota_service_client_transport_session_collision(transport_name): - creds1 = ga_credentials.AnonymousCredentials() - creds2 = ga_credentials.AnonymousCredentials() - client1 = QuotaServiceClient( - credentials=creds1, - transport=transport_name, - ) - client2 = QuotaServiceClient( - credentials=creds2, - transport=transport_name, - ) - session1 = client1.transport.list_quota_groups._session - session2 = client2.transport.list_quota_groups._session - assert session1 != session2 -def test_quota_service_grpc_transport_channel(): - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.QuotaServiceGrpcTransport( - 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_quota_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.QuotaServiceGrpcAsyncIOTransport( - 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.QuotaServiceGrpcTransport, transports.QuotaServiceGrpcAsyncIOTransport]) -def test_quota_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.QuotaServiceGrpcTransport, transports.QuotaServiceGrpcAsyncIOTransport]) -def test_quota_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_quota_group_path(): - account = "squid" - group = "clam" - expected = "accounts/{account}/groups/{group}".format(account=account, group=group, ) - actual = QuotaServiceClient.quota_group_path(account, group) - assert expected == actual - - -def test_parse_quota_group_path(): - expected = { - "account": "whelk", - "group": "octopus", - } - path = QuotaServiceClient.quota_group_path(**expected) - - # Check that the path construction is reversible. - actual = QuotaServiceClient.parse_quota_group_path(path) - assert expected == actual - -def test_common_billing_account_path(): - billing_account = "oyster" - expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - actual = QuotaServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "nudibranch", - } - path = QuotaServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = QuotaServiceClient.parse_common_billing_account_path(path) - assert expected == actual - -def test_common_folder_path(): - folder = "cuttlefish" - expected = "folders/{folder}".format(folder=folder, ) - actual = QuotaServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "mussel", - } - path = QuotaServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = QuotaServiceClient.parse_common_folder_path(path) - assert expected == actual - -def test_common_organization_path(): - organization = "winkle" - expected = "organizations/{organization}".format(organization=organization, ) - actual = QuotaServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "nautilus", - } - path = QuotaServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = QuotaServiceClient.parse_common_organization_path(path) - assert expected == actual - -def test_common_project_path(): - project = "scallop" - expected = "projects/{project}".format(project=project, ) - actual = QuotaServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "abalone", - } - path = QuotaServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = QuotaServiceClient.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 = QuotaServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "whelk", - "location": "octopus", - } - path = QuotaServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = QuotaServiceClient.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.QuotaServiceTransport, '_prep_wrapped_messages') as prep: - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object(transports.QuotaServiceTransport, '_prep_wrapped_messages') as prep: - transport_class = QuotaServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -def test_transport_close_grpc(): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc" - ) - with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -@pytest.mark.asyncio -async def test_transport_close_grpc_asyncio(): - client = QuotaServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio" - ) - with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: - async with client: - close.assert_not_called() - close.assert_called_once() - - -def test_transport_close_rest(): - client = QuotaServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - with mock.patch.object(type(getattr(client.transport, "_session")), "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 = QuotaServiceClient( - 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", [ - (QuotaServiceClient, transports.QuotaServiceGrpcTransport), - (QuotaServiceAsyncClient, transports.QuotaServiceGrpcAsyncIOTransport), -]) -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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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/google-shopping-merchant-reports/v1beta/.coveragerc b/owl-bot-staging/google-shopping-merchant-reports/v1beta/.coveragerc deleted file mode 100644 index ee0fc2257adb..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/.coveragerc +++ /dev/null @@ -1,13 +0,0 @@ -[run] -branch = True - -[report] -show_missing = True -omit = - google/shopping/merchant_reports/__init__.py - google/shopping/merchant_reports/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/google-shopping-merchant-reports/v1beta/.flake8 b/owl-bot-staging/google-shopping-merchant-reports/v1beta/.flake8 deleted file mode 100644 index 29227d4cf419..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/.flake8 +++ /dev/null @@ -1,33 +0,0 @@ -# -*- 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/google-shopping-merchant-reports/v1beta/MANIFEST.in b/owl-bot-staging/google-shopping-merchant-reports/v1beta/MANIFEST.in deleted file mode 100644 index baaee74264b4..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -recursive-include google/shopping/merchant_reports *.py -recursive-include google/shopping/merchant_reports_v1beta *.py diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/README.rst b/owl-bot-staging/google-shopping-merchant-reports/v1beta/README.rst deleted file mode 100644 index 33f7f87a7a6c..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/README.rst +++ /dev/null @@ -1,49 +0,0 @@ -Python Client for Google Shopping Merchant Reports 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 Shopping Merchant Reports 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/google-shopping-merchant-reports/v1beta/docs/_static/custom.css b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/_static/custom.css deleted file mode 100644 index 06423be0b592..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/_static/custom.css +++ /dev/null @@ -1,3 +0,0 @@ -dl.field-list > dt { - min-width: 100px -} diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/conf.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/conf.py deleted file mode 100644 index e082f6d42016..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/conf.py +++ /dev/null @@ -1,376 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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-shopping-merchant-reports 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-shopping-merchant-reports" -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 Shopping 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-shopping-merchant-reports-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-shopping-merchant-reports.tex", - u"google-shopping-merchant-reports 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-shopping-merchant-reports", - u"Google Shopping Merchant Reports 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-shopping-merchant-reports", - u"google-shopping-merchant-reports Documentation", - author, - "google-shopping-merchant-reports", - "GAPIC library for Google Shopping Merchant Reports 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/google-shopping-merchant-reports/v1beta/docs/index.rst b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/index.rst deleted file mode 100644 index 56b119bc9a3d..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/index.rst +++ /dev/null @@ -1,7 +0,0 @@ -API Reference -------------- -.. toctree:: - :maxdepth: 2 - - merchant_reports_v1beta/services_ - merchant_reports_v1beta/types_ diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/report_service.rst b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/report_service.rst deleted file mode 100644 index 38d2a647339e..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/report_service.rst +++ /dev/null @@ -1,10 +0,0 @@ -ReportService -------------------------------- - -.. automodule:: google.shopping.merchant_reports_v1beta.services.report_service - :members: - :inherited-members: - -.. automodule:: google.shopping.merchant_reports_v1beta.services.report_service.pagers - :members: - :inherited-members: diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/services_.rst b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/services_.rst deleted file mode 100644 index 55109976f640..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/services_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Services for Google Shopping Merchant Reports v1beta API -======================================================== -.. toctree:: - :maxdepth: 2 - - report_service diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/types_.rst b/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/types_.rst deleted file mode 100644 index 3f9d6a921dbd..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/docs/merchant_reports_v1beta/types_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Types for Google Shopping Merchant Reports v1beta API -===================================================== - -.. automodule:: google.shopping.merchant_reports_v1beta.types - :members: - :show-inheritance: diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/__init__.py deleted file mode 100644 index 9a1854b53a00..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/__init__.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.shopping.merchant_reports import gapic_version as package_version - -__version__ = package_version.__version__ - - -from google.shopping.merchant_reports_v1beta.services.report_service.client import ReportServiceClient -from google.shopping.merchant_reports_v1beta.services.report_service.async_client import ReportServiceAsyncClient - -from google.shopping.merchant_reports_v1beta.types.reports import BestSellersBrandView -from google.shopping.merchant_reports_v1beta.types.reports import BestSellersProductClusterView -from google.shopping.merchant_reports_v1beta.types.reports import CompetitiveVisibilityBenchmarkView -from google.shopping.merchant_reports_v1beta.types.reports import CompetitiveVisibilityCompetitorView -from google.shopping.merchant_reports_v1beta.types.reports import CompetitiveVisibilityTopMerchantView -from google.shopping.merchant_reports_v1beta.types.reports import MarketingMethod -from google.shopping.merchant_reports_v1beta.types.reports import NonProductPerformanceView -from google.shopping.merchant_reports_v1beta.types.reports import PriceCompetitivenessProductView -from google.shopping.merchant_reports_v1beta.types.reports import PriceInsightsProductView -from google.shopping.merchant_reports_v1beta.types.reports import ProductPerformanceView -from google.shopping.merchant_reports_v1beta.types.reports import ProductView -from google.shopping.merchant_reports_v1beta.types.reports import RelativeDemand -from google.shopping.merchant_reports_v1beta.types.reports import RelativeDemandChangeType -from google.shopping.merchant_reports_v1beta.types.reports import ReportGranularity -from google.shopping.merchant_reports_v1beta.types.reports import ReportRow -from google.shopping.merchant_reports_v1beta.types.reports import SearchRequest -from google.shopping.merchant_reports_v1beta.types.reports import SearchResponse -from google.shopping.merchant_reports_v1beta.types.reports import TrafficSource - -__all__ = ('ReportServiceClient', - 'ReportServiceAsyncClient', - 'BestSellersBrandView', - 'BestSellersProductClusterView', - 'CompetitiveVisibilityBenchmarkView', - 'CompetitiveVisibilityCompetitorView', - 'CompetitiveVisibilityTopMerchantView', - 'MarketingMethod', - 'NonProductPerformanceView', - 'PriceCompetitivenessProductView', - 'PriceInsightsProductView', - 'ProductPerformanceView', - 'ProductView', - 'RelativeDemand', - 'RelativeDemandChangeType', - 'ReportGranularity', - 'ReportRow', - 'SearchRequest', - 'SearchResponse', - 'TrafficSource', -) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/gapic_version.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/gapic_version.py deleted file mode 100644 index 558c8aab67c5..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/gapic_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/py.typed b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/py.typed deleted file mode 100644 index 925c5df4dab6..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-shopping-merchant-reports package uses inline types. diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/__init__.py deleted file mode 100644 index 3f709e1477bb..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/__init__.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.shopping.merchant_reports_v1beta import gapic_version as package_version - -__version__ = package_version.__version__ - - -from .services.report_service import ReportServiceClient -from .services.report_service import ReportServiceAsyncClient - -from .types.reports import BestSellersBrandView -from .types.reports import BestSellersProductClusterView -from .types.reports import CompetitiveVisibilityBenchmarkView -from .types.reports import CompetitiveVisibilityCompetitorView -from .types.reports import CompetitiveVisibilityTopMerchantView -from .types.reports import MarketingMethod -from .types.reports import NonProductPerformanceView -from .types.reports import PriceCompetitivenessProductView -from .types.reports import PriceInsightsProductView -from .types.reports import ProductPerformanceView -from .types.reports import ProductView -from .types.reports import RelativeDemand -from .types.reports import RelativeDemandChangeType -from .types.reports import ReportGranularity -from .types.reports import ReportRow -from .types.reports import SearchRequest -from .types.reports import SearchResponse -from .types.reports import TrafficSource - -__all__ = ( - 'ReportServiceAsyncClient', -'BestSellersBrandView', -'BestSellersProductClusterView', -'CompetitiveVisibilityBenchmarkView', -'CompetitiveVisibilityCompetitorView', -'CompetitiveVisibilityTopMerchantView', -'MarketingMethod', -'NonProductPerformanceView', -'PriceCompetitivenessProductView', -'PriceInsightsProductView', -'ProductPerformanceView', -'ProductView', -'RelativeDemand', -'RelativeDemandChangeType', -'ReportGranularity', -'ReportRow', -'ReportServiceClient', -'SearchRequest', -'SearchResponse', -'TrafficSource', -) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_metadata.json b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_metadata.json deleted file mode 100644 index 77c560dce3aa..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_metadata.json +++ /dev/null @@ -1,43 +0,0 @@ - { - "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", - "language": "python", - "libraryPackage": "google.shopping.merchant_reports_v1beta", - "protoPackage": "google.shopping.merchant.reports.v1beta", - "schema": "1.0", - "services": { - "ReportService": { - "clients": { - "grpc": { - "libraryClient": "ReportServiceClient", - "rpcs": { - "Search": { - "methods": [ - "search" - ] - } - } - }, - "grpc-async": { - "libraryClient": "ReportServiceAsyncClient", - "rpcs": { - "Search": { - "methods": [ - "search" - ] - } - } - }, - "rest": { - "libraryClient": "ReportServiceClient", - "rpcs": { - "Search": { - "methods": [ - "search" - ] - } - } - } - } - } - } -} diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_version.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_version.py deleted file mode 100644 index 558c8aab67c5..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/gapic_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/py.typed b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/py.typed deleted file mode 100644 index 925c5df4dab6..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-shopping-merchant-reports package uses inline types. diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/__init__.py deleted file mode 100644 index 8f6cf068242c..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/__init__.py deleted file mode 100644 index 90845062383d..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 ReportServiceClient -from .async_client import ReportServiceAsyncClient - -__all__ = ( - 'ReportServiceClient', - 'ReportServiceAsyncClient', -) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/async_client.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/async_client.py deleted file mode 100644 index 30efef354296..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/async_client.py +++ /dev/null @@ -1,361 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 re -from typing import Dict, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union - -from google.shopping.merchant_reports_v1beta 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_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - - -try: - OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.shopping.merchant_reports_v1beta.services.report_service import pagers -from google.shopping.merchant_reports_v1beta.types import reports -from .transports.base import ReportServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc_asyncio import ReportServiceGrpcAsyncIOTransport -from .client import ReportServiceClient - - -class ReportServiceAsyncClient: - """Service for retrieving reports and insights about your - products, their performance, and their competitive environment - on Google. - """ - - _client: ReportServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ReportServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ReportServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ReportServiceClient._DEFAULT_ENDPOINT_TEMPLATE - _DEFAULT_UNIVERSE = ReportServiceClient._DEFAULT_UNIVERSE - - common_billing_account_path = staticmethod(ReportServiceClient.common_billing_account_path) - parse_common_billing_account_path = staticmethod(ReportServiceClient.parse_common_billing_account_path) - common_folder_path = staticmethod(ReportServiceClient.common_folder_path) - parse_common_folder_path = staticmethod(ReportServiceClient.parse_common_folder_path) - common_organization_path = staticmethod(ReportServiceClient.common_organization_path) - parse_common_organization_path = staticmethod(ReportServiceClient.parse_common_organization_path) - common_project_path = staticmethod(ReportServiceClient.common_project_path) - parse_common_project_path = staticmethod(ReportServiceClient.parse_common_project_path) - common_location_path = staticmethod(ReportServiceClient.common_location_path) - parse_common_location_path = staticmethod(ReportServiceClient.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: - ReportServiceAsyncClient: The constructed client. - """ - return ReportServiceClient.from_service_account_info.__func__(ReportServiceAsyncClient, 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: - ReportServiceAsyncClient: The constructed client. - """ - return ReportServiceClient.from_service_account_file.__func__(ReportServiceAsyncClient, 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 ReportServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ReportServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ReportServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ReportServiceClient.get_transport_class - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[Union[str, ReportServiceTransport, Callable[..., ReportServiceTransport]]] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the report service async 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 (Optional[Union[str,ReportServiceTransport,Callable[..., ReportServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ReportServiceTransport constructor. - 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. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "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). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS 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. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - 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. - """ - self._client = ReportServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - - ) - - async def search(self, - request: Optional[Union[reports.SearchRequest, 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.SearchAsyncPager: - r"""Retrieves a report defined by a search query. The response might - contain fewer rows than specified by ``page_size``. Rely on - ``next_page_token`` to determine if there are more rows to be - requested. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.shopping import merchant_reports_v1beta - - async def sample_search(): - # Create a client - client = merchant_reports_v1beta.ReportServiceAsyncClient() - - # Initialize request argument(s) - request = merchant_reports_v1beta.SearchRequest( - parent="parent_value", - query="query_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.shopping.merchant_reports_v1beta.types.SearchRequest, dict]]): - The request object. Request message for the ``ReportService.Search`` method. - parent (:class:`str`): - Required. Id of the account making - the call. Must be a standalone account - or an MCA subaccount. Format: - accounts/{account} - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - google.shopping.merchant_reports_v1beta.services.report_service.pagers.SearchAsyncPager: - Response message for the ReportService.Search 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.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, reports.SearchRequest): - request = reports.SearchRequest(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._client._transport._wrapped_methods[self._client._transport.search] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # 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, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ReportServiceAsyncClient": - 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__ = ( - "ReportServiceAsyncClient", -) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/client.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/client.py deleted file mode 100644 index a61603b38fdf..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/client.py +++ /dev/null @@ -1,708 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.shopping.merchant_reports_v1beta 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, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - -from google.shopping.merchant_reports_v1beta.services.report_service import pagers -from google.shopping.merchant_reports_v1beta.types import reports -from .transports.base import ReportServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import ReportServiceGrpcTransport -from .transports.grpc_asyncio import ReportServiceGrpcAsyncIOTransport -from .transports.rest import ReportServiceRestTransport - - -class ReportServiceClientMeta(type): - """Metaclass for the ReportService 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[ReportServiceTransport]] - _transport_registry["grpc"] = ReportServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ReportServiceGrpcAsyncIOTransport - _transport_registry["rest"] = ReportServiceRestTransport - - def get_transport_class(cls, - label: Optional[str] = None, - ) -> Type[ReportServiceTransport]: - """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 ReportServiceClient(metaclass=ReportServiceClientMeta): - """Service for retrieving reports and insights about your - products, their performance, and their competitive environment - on Google. - """ - - @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") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "merchantapi.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "merchantapi.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @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: - ReportServiceClient: 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: - ReportServiceClient: 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) -> ReportServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ReportServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def common_billing_account_path(billing_account: str, ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str,str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path(folder: str, ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format(folder=folder, ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str,str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path(organization: str, ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format(organization=organization, ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str,str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path(project: str, ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project, ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str,str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path(project: str, location: str, ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format(project=project, location=location, ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str,str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source(cls, client_options: Optional[client_options_lib.ClientOptions] = None): - """Deprecated. 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. - """ - - warnings.warn("get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning) - 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 - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false").lower() - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - 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`") - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint(api_override, client_cert_source, universe_domain, use_mtls_endpoint): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): - _default_universe = ReportServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError(f"mTLS is not supported in any universe other than {_default_universe}.") - api_endpoint = ReportServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ReportServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=universe_domain) - return api_endpoint - - @staticmethod - def _get_universe_domain(client_universe_domain: Optional[str], universe_domain_env: Optional[str]) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ReportServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - @staticmethod - def _compare_universes(client_universe: str, - credentials: ga_credentials.Credentials) -> bool: - """Returns True iff the universe domains used by the client and credentials match. - - Args: - client_universe (str): The universe domain configured via the client options. - credentials (ga_credentials.Credentials): The credentials being used in the client. - - Returns: - bool: True iff client_universe matches the universe in credentials. - - Raises: - ValueError: when client_universe does not match the universe in credentials. - """ - - default_universe = ReportServiceClient._DEFAULT_UNIVERSE - credentials_universe = getattr(credentials, "universe_domain", default_universe) - - if client_universe != credentials_universe: - raise ValueError("The configured universe domain " - f"({client_universe}) does not match the universe domain " - f"found in the credentials ({credentials_universe}). " - "If you haven't configured the universe domain explicitly, " - f"`{default_universe}` is the default.") - return True - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - self._is_universe_domain_valid = (self._is_universe_domain_valid or - ReportServiceClient._compare_universes(self.universe_domain, self.transport._credentials)) - return self._is_universe_domain_valid - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[Union[str, ReportServiceTransport, Callable[..., ReportServiceTransport]]] = None, - client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the report 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 (Optional[Union[str,ReportServiceTransport,Callable[..., ReportServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ReportServiceTransport constructor. - 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. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "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). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS 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. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - 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. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict(self._client_options) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast(client_options_lib.ClientOptions, self._client_options) - - universe_domain_opt = getattr(self._client_options, 'universe_domain', None) - - self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = ReportServiceClient._read_environment_variables() - self._client_cert_source = ReportServiceClient._get_client_cert_source(self._client_options.client_cert_source, self._use_client_cert) - self._universe_domain = ReportServiceClient._get_universe_domain(universe_domain_opt, self._universe_domain_env) - self._api_endpoint = None # updated below, depending on `transport` - - # Initialize the universe domain validation. - self._is_universe_domain_valid = False - - api_key_value = getattr(self._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. - transport_provided = isinstance(transport, ReportServiceTransport) - if transport_provided: - # transport is a ReportServiceTransport instance. - if credentials or self._client_options.credentials_file or api_key_value: - raise ValueError("When providing a transport instance, " - "provide its credentials directly.") - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(ReportServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = (self._api_endpoint or - ReportServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint)) - - if not transport_provided: - 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_init: Union[Type[ReportServiceTransport], Callable[..., ReportServiceTransport]] = ( - ReportServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., ReportServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - api_audience=self._client_options.api_audience, - ) - - def search(self, - request: Optional[Union[reports.SearchRequest, 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.SearchPager: - r"""Retrieves a report defined by a search query. The response might - contain fewer rows than specified by ``page_size``. Rely on - ``next_page_token`` to determine if there are more rows to be - requested. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.shopping import merchant_reports_v1beta - - def sample_search(): - # Create a client - client = merchant_reports_v1beta.ReportServiceClient() - - # Initialize request argument(s) - request = merchant_reports_v1beta.SearchRequest( - parent="parent_value", - query="query_value", - ) - - # Make the request - page_result = client.search(request=request) - - # Handle the response - for response in page_result: - print(response) - - Args: - request (Union[google.shopping.merchant_reports_v1beta.types.SearchRequest, dict]): - The request object. Request message for the ``ReportService.Search`` method. - parent (str): - Required. Id of the account making - the call. Must be a standalone account - or an MCA subaccount. Format: - accounts/{account} - - 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.shopping.merchant_reports_v1beta.services.report_service.pagers.SearchPager: - Response message for the ReportService.Search 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.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, reports.SearchRequest): - request = reports.SearchRequest(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.search] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # 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, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ReportServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - - - - - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) - - -__all__ = ( - "ReportServiceClient", -) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/pagers.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/pagers.py deleted file mode 100644 index c69018f6bf97..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/pagers.py +++ /dev/null @@ -1,162 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import retry_async as retries_async -from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator, Union -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] - OptionalAsyncRetry = Union[retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore - -from google.shopping.merchant_reports_v1beta.types import reports - - -class SearchPager: - """A pager for iterating through ``search`` requests. - - This class thinly wraps an initial - :class:`google.shopping.merchant_reports_v1beta.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.shopping.merchant_reports_v1beta.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[..., reports.SearchResponse], - request: reports.SearchRequest, - response: reports.SearchResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.shopping.merchant_reports_v1beta.types.SearchRequest): - The initial request object. - response (google.shopping.merchant_reports_v1beta.types.SearchResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = reports.SearchRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[reports.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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) - yield self._response - - def __iter__(self) -> Iterator[reports.ReportRow]: - 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.shopping.merchant_reports_v1beta.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.shopping.merchant_reports_v1beta.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[reports.SearchResponse]], - request: reports.SearchRequest, - response: reports.SearchResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.shopping.merchant_reports_v1beta.types.SearchRequest): - The initial request object. - response (google.shopping.merchant_reports_v1beta.types.SearchResponse): - The initial response object. - retry (google.api_core.retry.AsyncRetry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = reports.SearchRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages(self) -> AsyncIterator[reports.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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) - yield self._response - def __aiter__(self) -> AsyncIterator[reports.ReportRow]: - 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/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/README.rst b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/README.rst deleted file mode 100644 index 3ff494d6f149..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/README.rst +++ /dev/null @@ -1,9 +0,0 @@ - -transport inheritance structure -_______________________________ - -`ReportServiceTransport` is the ABC for all transports. -- public child `ReportServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). -- public child `ReportServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). -- private child `_BaseReportServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). -- public child `ReportServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/__init__.py deleted file mode 100644 index a2d3480db148..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/__init__.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 ReportServiceTransport -from .grpc import ReportServiceGrpcTransport -from .grpc_asyncio import ReportServiceGrpcAsyncIOTransport -from .rest import ReportServiceRestTransport -from .rest import ReportServiceRestInterceptor - - -# Compile a registry of transports. -_transport_registry = OrderedDict() # type: Dict[str, Type[ReportServiceTransport]] -_transport_registry['grpc'] = ReportServiceGrpcTransport -_transport_registry['grpc_asyncio'] = ReportServiceGrpcAsyncIOTransport -_transport_registry['rest'] = ReportServiceRestTransport - -__all__ = ( - 'ReportServiceTransport', - 'ReportServiceGrpcTransport', - 'ReportServiceGrpcAsyncIOTransport', - 'ReportServiceRestTransport', - 'ReportServiceRestInterceptor', -) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/base.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/base.py deleted file mode 100644 index 93d8c8bff712..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/base.py +++ /dev/null @@ -1,154 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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.shopping.merchant_reports_v1beta 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.shopping.merchant_reports_v1beta.types import reports - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) - - -class ReportServiceTransport(abc.ABC): - """Abstract transport class for ReportService.""" - - AUTH_SCOPES = ( - 'https://www.googleapis.com/auth/content', - ) - - DEFAULT_HOST: str = 'merchantapi.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 (default: 'merchantapi.googleapis.com'). - 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 not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # 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 and not self._ignore_credentials: - 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 - - @property - def host(self): - return self._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[ - [reports.SearchRequest], - Union[ - reports.SearchResponse, - Awaitable[reports.SearchResponse] - ]]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ( - 'ReportServiceTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc.py deleted file mode 100644 index 590b4dedd295..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc.py +++ /dev/null @@ -1,275 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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.shopping.merchant_reports_v1beta.types import reports -from .base import ReportServiceTransport, DEFAULT_CLIENT_INFO - - -class ReportServiceGrpcTransport(ReportServiceTransport): - """gRPC backend transport for ReportService. - - Service for retrieving reports and insights about your - products, their performance, and their competitive environment - on Google. - - 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 = 'merchantapi.googleapis.com', - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[grpc.Channel, Callable[..., 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 (default: 'merchantapi.googleapis.com'). - 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 a ``channel`` instance 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 a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # 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: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - 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 = 'merchantapi.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[ - [reports.SearchRequest], - reports.SearchResponse]: - r"""Return a callable for the search method over gRPC. - - Retrieves a report defined by a search query. The response might - contain fewer rows than specified by ``page_size``. Rely on - ``next_page_token`` to determine if there are more rows to be - requested. - - 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.shopping.merchant.reports.v1beta.ReportService/Search', - request_serializer=reports.SearchRequest.serialize, - response_deserializer=reports.SearchResponse.deserialize, - ) - return self._stubs['search'] - - def close(self): - self.grpc_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ( - 'ReportServiceGrpcTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py deleted file mode 100644 index 8aa8e5af0778..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,296 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 inspect -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 exceptions as core_exceptions -from google.api_core import retry_async as retries -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.shopping.merchant_reports_v1beta.types import reports -from .base import ReportServiceTransport, DEFAULT_CLIENT_INFO -from .grpc import ReportServiceGrpcTransport - - -class ReportServiceGrpcAsyncIOTransport(ReportServiceTransport): - """gRPC AsyncIO backend transport for ReportService. - - Service for retrieving reports and insights about your - products, their performance, and their competitive environment - on Google. - - 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 = 'merchantapi.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`. - 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 = 'merchantapi.googleapis.com', - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[aio.Channel, Callable[..., 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 (default: 'merchantapi.googleapis.com'). - 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 a ``channel`` instance 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 a ``channel`` instance 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[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # 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: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - 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._wrap_with_kind = "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters - 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[ - [reports.SearchRequest], - Awaitable[reports.SearchResponse]]: - r"""Return a callable for the search method over gRPC. - - Retrieves a report defined by a search query. The response might - contain fewer rows than specified by ``page_size``. Rely on - ``next_page_token`` to determine if there are more rows to be - requested. - - 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.shopping.merchant.reports.v1beta.ReportService/Search', - request_serializer=reports.SearchRequest.serialize, - response_deserializer=reports.SearchResponse.deserialize, - ) - return self._stubs['search'] - - def _prep_wrapped_messages(self, client_info): - """ Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.search: self._wrap_method( - self.search, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self.grpc_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ( - 'ReportServiceGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py deleted file mode 100644 index ed399060e330..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py +++ /dev/null @@ -1,279 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 -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 gapic_v1 - -from google.protobuf import json_format - -from requests import __version__ as requests_version -import dataclasses -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union -import warnings - - -from google.shopping.merchant_reports_v1beta.types import reports - - -from .rest_base import _BaseReportServiceRestTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, - grpc_version=None, - rest_version=f"requests@{requests_version}", -) - - -class ReportServiceRestInterceptor: - """Interceptor for ReportService. - - 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 ReportServiceRestTransport. - - .. code-block:: python - class MyCustomReportServiceInterceptor(ReportServiceRestInterceptor): - 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 = ReportServiceRestTransport(interceptor=MyCustomReportServiceInterceptor()) - client = ReportServiceClient(transport=transport) - - - """ - def pre_search(self, request: reports.SearchRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[reports.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 ReportService server. - """ - return request, metadata - - def post_search(self, response: reports.SearchResponse) -> reports.SearchResponse: - """Post-rpc interceptor for search - - Override in a subclass to manipulate the response - after it is returned by the ReportService server but before - it is returned to user code. - """ - return response - - -@dataclasses.dataclass -class ReportServiceRestStub: - _session: AuthorizedSession - _host: str - _interceptor: ReportServiceRestInterceptor - - -class ReportServiceRestTransport(_BaseReportServiceRestTransport): - """REST backend synchronous transport for ReportService. - - Service for retrieving reports and insights about your - products, their performance, and their competitive environment - on Google. - - 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 = 'merchantapi.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[ReportServiceRestInterceptor] = None, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'merchantapi.googleapis.com'). - 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 - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - url_scheme=url_scheme, - 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 ReportServiceRestInterceptor() - self._prep_wrapped_messages(client_info) - - class _Search(_BaseReportServiceRestTransport._BaseSearch, ReportServiceRestStub): - def __hash__(self): - return hash("ReportServiceRestTransport.Search") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, - ) - return response - - def __call__(self, - request: reports.SearchRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> reports.SearchResponse: - r"""Call the search method over HTTP. - - Args: - request (~.reports.SearchRequest): - The request object. Request message for the ``ReportService.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: - ~.reports.SearchResponse: - Response message for the ``ReportService.Search`` - method. - - """ - - http_options = _BaseReportServiceRestTransport._BaseSearch._get_http_options() - request, metadata = self._interceptor.pre_search(request, metadata) - transcoded_request = _BaseReportServiceRestTransport._BaseSearch._get_transcoded_request(http_options, request) - - body = _BaseReportServiceRestTransport._BaseSearch._get_request_body_json(transcoded_request) - - # Jsonify the query params - query_params = _BaseReportServiceRestTransport._BaseSearch._get_query_params_json(transcoded_request) - - # Send the request - response = ReportServiceRestTransport._Search._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = reports.SearchResponse() - pb_resp = reports.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[ - [reports.SearchRequest], - reports.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 kind(self) -> str: - return "rest" - - def close(self): - self._session.close() - - -__all__=( - 'ReportServiceRestTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest_base.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest_base.py deleted file mode 100644 index b7f01e752a42..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest_base.py +++ /dev/null @@ -1,138 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 json # type: ignore -from google.api_core import path_template -from google.api_core import gapic_v1 - -from google.protobuf import json_format -from .base import ReportServiceTransport, DEFAULT_CLIENT_INFO - -import re -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union - - -from google.shopping.merchant_reports_v1beta.types import reports - - -class _BaseReportServiceRestTransport(ReportServiceTransport): - """Base REST backend transport for ReportService. - - Note: This class is not meant to be used directly. Use its sync and - async sub-classes instead. - - 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 = 'merchantapi.googleapis.com', - credentials: Optional[Any] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - url_scheme: str = 'https', - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - Args: - host (Optional[str]): - The hostname to connect to (default: 'merchantapi.googleapis.com'). - credentials (Optional[Any]): 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. - 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 - 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 - ) - - class _BaseSearch: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'post', - 'uri': '/reports/v1beta/{parent=accounts/*}/reports:search', - 'body': '*', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = reports.SearchRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_request_body_json(transcoded_request): - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request['body'], - use_integers_for_enums=True - ) - return body - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseReportServiceRestTransport._BaseSearch._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - -__all__=( - '_BaseReportServiceRestTransport', -) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/__init__.py deleted file mode 100644 index 5e965be69091..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/__init__.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .reports import ( - BestSellersBrandView, - BestSellersProductClusterView, - CompetitiveVisibilityBenchmarkView, - CompetitiveVisibilityCompetitorView, - CompetitiveVisibilityTopMerchantView, - MarketingMethod, - NonProductPerformanceView, - PriceCompetitivenessProductView, - PriceInsightsProductView, - ProductPerformanceView, - ProductView, - RelativeDemand, - RelativeDemandChangeType, - ReportGranularity, - ReportRow, - SearchRequest, - SearchResponse, - TrafficSource, -) - -__all__ = ( - 'BestSellersBrandView', - 'BestSellersProductClusterView', - 'CompetitiveVisibilityBenchmarkView', - 'CompetitiveVisibilityCompetitorView', - 'CompetitiveVisibilityTopMerchantView', - 'MarketingMethod', - 'NonProductPerformanceView', - 'PriceCompetitivenessProductView', - 'PriceInsightsProductView', - 'ProductPerformanceView', - 'ProductView', - 'RelativeDemand', - 'RelativeDemandChangeType', - 'ReportGranularity', - 'ReportRow', - 'SearchRequest', - 'SearchResponse', - 'TrafficSource', -) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/reports.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/reports.py deleted file mode 100644 index 49712fcea3ab..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/google/shopping/merchant_reports_v1beta/types/reports.py +++ /dev/null @@ -1,2521 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.shopping.type.types import types -from google.type import date_pb2 # type: ignore - - -__protobuf__ = proto.module( - package='google.shopping.merchant.reports.v1beta', - manifest={ - 'SearchRequest', - 'SearchResponse', - 'ReportRow', - 'ProductPerformanceView', - 'ProductView', - 'PriceCompetitivenessProductView', - 'PriceInsightsProductView', - 'BestSellersProductClusterView', - 'BestSellersBrandView', - 'NonProductPerformanceView', - 'CompetitiveVisibilityCompetitorView', - 'CompetitiveVisibilityTopMerchantView', - 'CompetitiveVisibilityBenchmarkView', - 'MarketingMethod', - 'ReportGranularity', - 'RelativeDemand', - 'RelativeDemandChangeType', - 'TrafficSource', - }, -) - - -class SearchRequest(proto.Message): - r"""Request message for the ``ReportService.Search`` method. - - Attributes: - parent (str): - Required. Id of the account making the call. - Must be a standalone account or an MCA - subaccount. Format: accounts/{account} - query (str): - Required. Query that defines a report to be - retrieved. - For details on how to construct your query, see - the Query Language guide. For the full list of - available tables and fields, see the Available - fields. - page_size (int): - Optional. Number of ``ReportRows`` to retrieve in a single - page. Defaults to 1000. Values above 5000 are coerced to - 5000. - page_token (str): - Optional. Token of the page to retrieve. If not specified, - the first page of results is returned. In order to request - the next page of results, the value obtained from - ``next_page_token`` in the previous response should be used. - """ - - parent: str = proto.Field( - proto.STRING, - number=1, - ) - query: str = proto.Field( - proto.STRING, - number=2, - ) - page_size: int = proto.Field( - proto.INT32, - number=3, - ) - page_token: str = proto.Field( - proto.STRING, - number=4, - ) - - -class SearchResponse(proto.Message): - r"""Response message for the ``ReportService.Search`` method. - - Attributes: - results (MutableSequence[google.shopping.merchant_reports_v1beta.types.ReportRow]): - Rows that matched the search query. - next_page_token (str): - Token which can be sent as ``page_token`` to retrieve the - next page. If omitted, there are no subsequent pages. - """ - - @property - def raw_page(self): - return self - - results: MutableSequence['ReportRow'] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message='ReportRow', - ) - next_page_token: str = proto.Field( - proto.STRING, - number=2, - ) - - -class ReportRow(proto.Message): - r"""Result row returned from the search query. - - Only the message corresponding to the queried table is populated - in the response. Within the populated message, only the fields - requested explicitly in the query are populated. - - Attributes: - product_performance_view (google.shopping.merchant_reports_v1beta.types.ProductPerformanceView): - Fields available for query in ``product_performance_view`` - table. - non_product_performance_view (google.shopping.merchant_reports_v1beta.types.NonProductPerformanceView): - Fields available for query in - ``non_product_performance_view`` table. - product_view (google.shopping.merchant_reports_v1beta.types.ProductView): - Fields available for query in ``product_view`` table. - price_competitiveness_product_view (google.shopping.merchant_reports_v1beta.types.PriceCompetitivenessProductView): - Fields available for query in - ``price_competitiveness_product_view`` table. - price_insights_product_view (google.shopping.merchant_reports_v1beta.types.PriceInsightsProductView): - Fields available for query in - ``price_insights_product_view`` table. - best_sellers_product_cluster_view (google.shopping.merchant_reports_v1beta.types.BestSellersProductClusterView): - Fields available for query in - ``best_sellers_product_cluster_view`` table. - best_sellers_brand_view (google.shopping.merchant_reports_v1beta.types.BestSellersBrandView): - Fields available for query in ``best_sellers_brand_view`` - table. - competitive_visibility_competitor_view (google.shopping.merchant_reports_v1beta.types.CompetitiveVisibilityCompetitorView): - Fields available for query in - ``competitive_visibility_competitor_view`` table. - competitive_visibility_top_merchant_view (google.shopping.merchant_reports_v1beta.types.CompetitiveVisibilityTopMerchantView): - Fields available for query in - ``competitive_visibility_top_merchant_view`` table. - competitive_visibility_benchmark_view (google.shopping.merchant_reports_v1beta.types.CompetitiveVisibilityBenchmarkView): - Fields available for query in - ``competitive_visibility_benchmark_view`` table. - """ - - product_performance_view: 'ProductPerformanceView' = proto.Field( - proto.MESSAGE, - number=1, - message='ProductPerformanceView', - ) - non_product_performance_view: 'NonProductPerformanceView' = proto.Field( - proto.MESSAGE, - number=7, - message='NonProductPerformanceView', - ) - product_view: 'ProductView' = proto.Field( - proto.MESSAGE, - number=2, - message='ProductView', - ) - price_competitiveness_product_view: 'PriceCompetitivenessProductView' = proto.Field( - proto.MESSAGE, - number=3, - message='PriceCompetitivenessProductView', - ) - price_insights_product_view: 'PriceInsightsProductView' = proto.Field( - proto.MESSAGE, - number=4, - message='PriceInsightsProductView', - ) - best_sellers_product_cluster_view: 'BestSellersProductClusterView' = proto.Field( - proto.MESSAGE, - number=5, - message='BestSellersProductClusterView', - ) - best_sellers_brand_view: 'BestSellersBrandView' = proto.Field( - proto.MESSAGE, - number=6, - message='BestSellersBrandView', - ) - competitive_visibility_competitor_view: 'CompetitiveVisibilityCompetitorView' = proto.Field( - proto.MESSAGE, - number=8, - message='CompetitiveVisibilityCompetitorView', - ) - competitive_visibility_top_merchant_view: 'CompetitiveVisibilityTopMerchantView' = proto.Field( - proto.MESSAGE, - number=9, - message='CompetitiveVisibilityTopMerchantView', - ) - competitive_visibility_benchmark_view: 'CompetitiveVisibilityBenchmarkView' = proto.Field( - proto.MESSAGE, - number=10, - message='CompetitiveVisibilityBenchmarkView', - ) - - -class ProductPerformanceView(proto.Message): - r"""Fields available for query in ``product_performance_view`` table. - - Product performance data for your account, including performance - metrics (for example, ``clicks``) and dimensions according to which - performance metrics are segmented (for example, ``offer_id``). - Values of product dimensions, such as ``offer_id``, reflect the - state of a product at the time of the impression. - - Segment fields cannot be selected in queries without also selecting - at least one metric field. - - Values are only set for fields requested explicitly in the request's - search query. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - marketing_method (google.shopping.merchant_reports_v1beta.types.MarketingMethod.MarketingMethodEnum): - Marketing method to which metrics apply. - Segment. - - This field is a member of `oneof`_ ``_marketing_method``. - date (google.type.date_pb2.Date): - Date in the merchant timezone to which metrics apply. - Segment. - - Condition on ``date`` is required in the ``WHERE`` clause. - week (google.type.date_pb2.Date): - First day of the week (Monday) of the metrics - date in the merchant timezone. Segment. - customer_country_code (str): - Code of the country where the customer is - located at the time of the event. Represented in - the ISO 3166 format. Segment. - - If the customer country cannot be determined, a - special 'ZZ' code is returned. - - This field is a member of `oneof`_ ``_customer_country_code``. - offer_id (str): - Merchant-provided id of the product. Segment. - - This field is a member of `oneof`_ ``_offer_id``. - title (str): - Title of the product. Segment. - - This field is a member of `oneof`_ ``_title``. - brand (str): - Brand of the product. Segment. - - This field is a member of `oneof`_ ``_brand``. - category_l1 (str): - `Product category (1st - level) `__ - in Google's product taxonomy. Segment. - - This field is a member of `oneof`_ ``_category_l1``. - category_l2 (str): - `Product category (2nd - level) `__ - in Google's product taxonomy. Segment. - - This field is a member of `oneof`_ ``_category_l2``. - category_l3 (str): - `Product category (3rd - level) `__ - in Google's product taxonomy. Segment. - - This field is a member of `oneof`_ ``_category_l3``. - category_l4 (str): - `Product category (4th - level) `__ - in Google's product taxonomy. Segment. - - This field is a member of `oneof`_ ``_category_l4``. - category_l5 (str): - `Product category (5th - level) `__ - in Google's product taxonomy. Segment. - - This field is a member of `oneof`_ ``_category_l5``. - product_type_l1 (str): - `Product type (1st - level) `__ - in merchant's own product taxonomy. Segment. - - This field is a member of `oneof`_ ``_product_type_l1``. - product_type_l2 (str): - `Product type (2nd - level) `__ - in merchant's own product taxonomy. Segment. - - This field is a member of `oneof`_ ``_product_type_l2``. - product_type_l3 (str): - `Product type (3rd - level) `__ - in merchant's own product taxonomy. Segment. - - This field is a member of `oneof`_ ``_product_type_l3``. - product_type_l4 (str): - `Product type (4th - level) `__ - in merchant's own product taxonomy. Segment. - - This field is a member of `oneof`_ ``_product_type_l4``. - product_type_l5 (str): - `Product type (5th - level) `__ - in merchant's own product taxonomy. Segment. - - This field is a member of `oneof`_ ``_product_type_l5``. - custom_label0 (str): - Custom label 0 for custom grouping of - products. Segment. - - This field is a member of `oneof`_ ``_custom_label0``. - custom_label1 (str): - Custom label 1 for custom grouping of - products. Segment. - - This field is a member of `oneof`_ ``_custom_label1``. - custom_label2 (str): - Custom label 2 for custom grouping of - products. Segment. - - This field is a member of `oneof`_ ``_custom_label2``. - custom_label3 (str): - Custom label 3 for custom grouping of - products. Segment. - - This field is a member of `oneof`_ ``_custom_label3``. - custom_label4 (str): - Custom label 4 for custom grouping of - products. Segment. - - This field is a member of `oneof`_ ``_custom_label4``. - clicks (int): - Number of clicks. Metric. - - This field is a member of `oneof`_ ``_clicks``. - impressions (int): - Number of times merchant's products are - shown. Metric. - - This field is a member of `oneof`_ ``_impressions``. - click_through_rate (float): - Click-through rate - the number of clicks - merchant's products receive (clicks) divided by - the number of times the products are shown - (impressions). Metric. - - This field is a member of `oneof`_ ``_click_through_rate``. - conversions (float): - Number of conversions attributed to the product, reported on - the conversion date. Depending on the attribution model, a - conversion might be distributed across multiple clicks, - where each click gets its own credit assigned. This metric - is a sum of all such credits. Metric. - - Available only for the ``FREE`` traffic source. - - This field is a member of `oneof`_ ``_conversions``. - conversion_value (google.shopping.type.types.Price): - Value of conversions attributed to the product, reported on - the conversion date. Metric. - - Available only for the ``FREE`` traffic source. - conversion_rate (float): - Number of conversions divided by the number of clicks, - reported on the impression date. Metric. - - Available only for the ``FREE`` traffic source. - - This field is a member of `oneof`_ ``_conversion_rate``. - """ - - marketing_method: 'MarketingMethod.MarketingMethodEnum' = proto.Field( - proto.ENUM, - number=1, - optional=True, - enum='MarketingMethod.MarketingMethodEnum', - ) - date: date_pb2.Date = proto.Field( - proto.MESSAGE, - number=2, - message=date_pb2.Date, - ) - week: date_pb2.Date = proto.Field( - proto.MESSAGE, - number=3, - message=date_pb2.Date, - ) - customer_country_code: str = proto.Field( - proto.STRING, - number=4, - optional=True, - ) - offer_id: str = proto.Field( - proto.STRING, - number=5, - optional=True, - ) - title: str = proto.Field( - proto.STRING, - number=6, - optional=True, - ) - brand: str = proto.Field( - proto.STRING, - number=7, - optional=True, - ) - category_l1: str = proto.Field( - proto.STRING, - number=8, - optional=True, - ) - category_l2: str = proto.Field( - proto.STRING, - number=9, - optional=True, - ) - category_l3: str = proto.Field( - proto.STRING, - number=10, - optional=True, - ) - category_l4: str = proto.Field( - proto.STRING, - number=11, - optional=True, - ) - category_l5: str = proto.Field( - proto.STRING, - number=12, - optional=True, - ) - product_type_l1: str = proto.Field( - proto.STRING, - number=13, - optional=True, - ) - product_type_l2: str = proto.Field( - proto.STRING, - number=14, - optional=True, - ) - product_type_l3: str = proto.Field( - proto.STRING, - number=15, - optional=True, - ) - product_type_l4: str = proto.Field( - proto.STRING, - number=16, - optional=True, - ) - product_type_l5: str = proto.Field( - proto.STRING, - number=17, - optional=True, - ) - custom_label0: str = proto.Field( - proto.STRING, - number=18, - optional=True, - ) - custom_label1: str = proto.Field( - proto.STRING, - number=19, - optional=True, - ) - custom_label2: str = proto.Field( - proto.STRING, - number=20, - optional=True, - ) - custom_label3: str = proto.Field( - proto.STRING, - number=21, - optional=True, - ) - custom_label4: str = proto.Field( - proto.STRING, - number=22, - optional=True, - ) - clicks: int = proto.Field( - proto.INT64, - number=23, - optional=True, - ) - impressions: int = proto.Field( - proto.INT64, - number=24, - optional=True, - ) - click_through_rate: float = proto.Field( - proto.DOUBLE, - number=25, - optional=True, - ) - conversions: float = proto.Field( - proto.DOUBLE, - number=26, - optional=True, - ) - conversion_value: types.Price = proto.Field( - proto.MESSAGE, - number=27, - message=types.Price, - ) - conversion_rate: float = proto.Field( - proto.DOUBLE, - number=28, - optional=True, - ) - - -class ProductView(proto.Message): - r"""Fields available for query in ``product_view`` table. - - Products in the current inventory. Products in this table are the - same as in Products sub-API but not all product attributes from - Products sub-API are available for query in this table. In contrast - to Products sub-API, this table allows to filter the returned list - of products by product attributes. To retrieve a single product by - ``id`` or list all products, Products sub-API should be used. - - Values are only set for fields requested explicitly in the request's - search query. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - id (str): - REST ID of the product, in the form of - ``channel~languageCode~feedLabel~offerId``. Merchant API - methods that operate on products take this as their ``name`` - parameter. - - Required in the ``SELECT`` clause. - - This field is a member of `oneof`_ ``_id``. - channel (google.shopping.type.types.Channel.ChannelEnum): - Channel of the product. Can be ``ONLINE`` or ``LOCAL``. - - This field is a member of `oneof`_ ``_channel``. - language_code (str): - Language code of the product in BCP 47 - format. - - This field is a member of `oneof`_ ``_language_code``. - feed_label (str): - Feed label of the product. - - This field is a member of `oneof`_ ``_feed_label``. - offer_id (str): - Merchant-provided id of the product. - - This field is a member of `oneof`_ ``_offer_id``. - title (str): - Title of the product. - - This field is a member of `oneof`_ ``_title``. - brand (str): - Brand of the product. - - This field is a member of `oneof`_ ``_brand``. - category_l1 (str): - Product category (1st level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l1``. - category_l2 (str): - Product category (2nd level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l2``. - category_l3 (str): - Product category (3rd level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l3``. - category_l4 (str): - Product category (4th level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l4``. - category_l5 (str): - Product category (5th level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l5``. - product_type_l1 (str): - Product type (1st level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l1``. - product_type_l2 (str): - Product type (2nd level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l2``. - product_type_l3 (str): - Product type (3rd level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l3``. - product_type_l4 (str): - Product type (4th level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l4``. - product_type_l5 (str): - Product type (5th level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l5``. - price (google.shopping.type.types.Price): - Product price. Absent if the information - about the price of the product is not available. - condition (str): - `Condition `__ - of the product. - - This field is a member of `oneof`_ ``_condition``. - availability (str): - `Availability `__ - of the product. - - This field is a member of `oneof`_ ``_availability``. - shipping_label (str): - Normalized `shipping - label `__ - specified in the data source. - - This field is a member of `oneof`_ ``_shipping_label``. - gtin (MutableSequence[str]): - List of Global Trade Item Numbers (GTINs) of - the product. - item_group_id (str): - Item group id provided by the merchant for - grouping variants together. - - This field is a member of `oneof`_ ``_item_group_id``. - thumbnail_link (str): - Link to the processed image of the product, - hosted on the Google infrastructure. - - This field is a member of `oneof`_ ``_thumbnail_link``. - creation_time (google.protobuf.timestamp_pb2.Timestamp): - The time the merchant created the product in - timestamp seconds. - expiration_date (google.type.date_pb2.Date): - Expiration date for the product, specified on - insertion. - aggregated_reporting_context_status (google.shopping.merchant_reports_v1beta.types.ProductView.AggregatedReportingContextStatus): - Aggregated status. - - This field is a member of `oneof`_ ``_aggregated_reporting_context_status``. - item_issues (MutableSequence[google.shopping.merchant_reports_v1beta.types.ProductView.ItemIssue]): - List of item issues for the product. - - **This field cannot be used for sorting the results.** - - **Only selected attributes of this field (for example, - ``item_issues.severity.aggregated_severity``) can be used - for filtering the results.** - click_potential (google.shopping.merchant_reports_v1beta.types.ProductView.ClickPotential): - Estimated performance potential compared to - highest performing products of the merchant. - click_potential_rank (int): - Rank of the product based on its click potential. A product - with ``click_potential_rank`` 1 has the highest click - potential among the merchant's products that fulfill the - search query conditions. - - This field is a member of `oneof`_ ``_click_potential_rank``. - """ - class AggregatedReportingContextStatus(proto.Enum): - r"""Status of the product aggregated for all reporting contexts. - - Here's an example of how the aggregated status is computed: - - Free listings \| Shopping ads \| Status - --------------|--------------|------------------------------ - Approved \| Approved \| ELIGIBLE Approved \| Pending \| ELIGIBLE - Approved \| Disapproved \| ELIGIBLE_LIMITED Pending \| Pending \| - PENDING Disapproved \| Disapproved \| NOT_ELIGIBLE_OR_DISAPPROVED - - Values: - AGGREGATED_REPORTING_CONTEXT_STATUS_UNSPECIFIED (0): - Not specified. - NOT_ELIGIBLE_OR_DISAPPROVED (1): - Product is not eligible or is disapproved for - all reporting contexts. - PENDING (2): - Product's status is pending in all reporting - contexts. - ELIGIBLE_LIMITED (3): - Product is eligible for some (but not all) - reporting contexts. - ELIGIBLE (4): - Product is eligible for all reporting - contexts. - """ - AGGREGATED_REPORTING_CONTEXT_STATUS_UNSPECIFIED = 0 - NOT_ELIGIBLE_OR_DISAPPROVED = 1 - PENDING = 2 - ELIGIBLE_LIMITED = 3 - ELIGIBLE = 4 - - class ClickPotential(proto.Enum): - r"""A product's `click - potential `__ - estimates its performance potential compared to highest performing - products of the merchant. Click potential of a product helps - merchants to prioritize which products to fix and helps them - understand how products are performing against their potential. - - Values: - CLICK_POTENTIAL_UNSPECIFIED (0): - Unknown predicted clicks impact. - LOW (1): - Potential to receive a low number of clicks - compared to the highest performing products of - the merchant. - MEDIUM (2): - Potential to receive a moderate number of - clicks compared to the highest performing - products of the merchant. - HIGH (3): - Potential to receive a similar number of - clicks as the highest performing products of the - merchant. - """ - CLICK_POTENTIAL_UNSPECIFIED = 0 - LOW = 1 - MEDIUM = 2 - HIGH = 3 - - class ItemIssue(proto.Message): - r"""Item issue associated with the product. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - type_ (google.shopping.merchant_reports_v1beta.types.ProductView.ItemIssue.ItemIssueType): - Item issue type. - severity (google.shopping.merchant_reports_v1beta.types.ProductView.ItemIssue.ItemIssueSeverity): - Item issue severity. - resolution (google.shopping.merchant_reports_v1beta.types.ProductView.ItemIssue.ItemIssueResolution): - Item issue resolution. - - This field is a member of `oneof`_ ``_resolution``. - """ - class ItemIssueResolution(proto.Enum): - r"""How to resolve the issue. - - Values: - ITEM_ISSUE_RESOLUTION_UNSPECIFIED (0): - Not specified. - MERCHANT_ACTION (1): - The merchant has to fix the issue. - PENDING_PROCESSING (2): - The issue will be resolved automatically (for - example, image crawl) or through a Google - review. No merchant action is required now. - Resolution might lead to another issue (for - example, if crawl fails). - """ - ITEM_ISSUE_RESOLUTION_UNSPECIFIED = 0 - MERCHANT_ACTION = 1 - PENDING_PROCESSING = 2 - - class ItemIssueType(proto.Message): - r"""Issue type. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - code (str): - Error code of the issue, equivalent to the ``code`` of - `Product - issues `__. - - This field is a member of `oneof`_ ``_code``. - canonical_attribute (str): - Canonical attribute name for - attribute-specific issues. - - This field is a member of `oneof`_ ``_canonical_attribute``. - """ - - code: str = proto.Field( - proto.STRING, - number=1, - optional=True, - ) - canonical_attribute: str = proto.Field( - proto.STRING, - number=2, - optional=True, - ) - - class ItemIssueSeverity(proto.Message): - r"""How the issue affects the serving of the product. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - severity_per_reporting_context (MutableSequence[google.shopping.merchant_reports_v1beta.types.ProductView.ItemIssue.ItemIssueSeverity.IssueSeverityPerReportingContext]): - Issue severity per reporting context. - aggregated_severity (google.shopping.merchant_reports_v1beta.types.ProductView.ItemIssue.ItemIssueSeverity.AggregatedIssueSeverity): - Aggregated severity of the issue for all reporting contexts - it affects. - - **This field can be used for filtering the results.** - - This field is a member of `oneof`_ ``_aggregated_severity``. - """ - class AggregatedIssueSeverity(proto.Enum): - r"""Issue severity aggregated for all reporting contexts. - - Values: - AGGREGATED_ISSUE_SEVERITY_UNSPECIFIED (0): - Not specified. - DISAPPROVED (1): - Issue disapproves the product in at least one - reporting context. - DEMOTED (2): - Issue demotes the product in all reporting - contexts it affects. - PENDING (3): - Issue resolution is ``PENDING_PROCESSING``. - """ - AGGREGATED_ISSUE_SEVERITY_UNSPECIFIED = 0 - DISAPPROVED = 1 - DEMOTED = 2 - PENDING = 3 - - class IssueSeverityPerReportingContext(proto.Message): - r"""Issue severity per reporting context. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - reporting_context (google.shopping.type.types.ReportingContext.ReportingContextEnum): - Reporting context the issue applies to. - - This field is a member of `oneof`_ ``_reporting_context``. - disapproved_countries (MutableSequence[str]): - List of disapproved countries in the - reporting context, represented in ISO 3166 - format. - demoted_countries (MutableSequence[str]): - List of demoted countries in the reporting - context, represented in ISO 3166 format. - """ - - reporting_context: types.ReportingContext.ReportingContextEnum = proto.Field( - proto.ENUM, - number=1, - optional=True, - enum=types.ReportingContext.ReportingContextEnum, - ) - disapproved_countries: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=2, - ) - demoted_countries: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=3, - ) - - severity_per_reporting_context: MutableSequence['ProductView.ItemIssue.ItemIssueSeverity.IssueSeverityPerReportingContext'] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message='ProductView.ItemIssue.ItemIssueSeverity.IssueSeverityPerReportingContext', - ) - aggregated_severity: 'ProductView.ItemIssue.ItemIssueSeverity.AggregatedIssueSeverity' = proto.Field( - proto.ENUM, - number=2, - optional=True, - enum='ProductView.ItemIssue.ItemIssueSeverity.AggregatedIssueSeverity', - ) - - type_: 'ProductView.ItemIssue.ItemIssueType' = proto.Field( - proto.MESSAGE, - number=1, - message='ProductView.ItemIssue.ItemIssueType', - ) - severity: 'ProductView.ItemIssue.ItemIssueSeverity' = proto.Field( - proto.MESSAGE, - number=2, - message='ProductView.ItemIssue.ItemIssueSeverity', - ) - resolution: 'ProductView.ItemIssue.ItemIssueResolution' = proto.Field( - proto.ENUM, - number=3, - optional=True, - enum='ProductView.ItemIssue.ItemIssueResolution', - ) - - id: str = proto.Field( - proto.STRING, - number=1, - optional=True, - ) - channel: types.Channel.ChannelEnum = proto.Field( - proto.ENUM, - number=28, - optional=True, - enum=types.Channel.ChannelEnum, - ) - language_code: str = proto.Field( - proto.STRING, - number=2, - optional=True, - ) - feed_label: str = proto.Field( - proto.STRING, - number=3, - optional=True, - ) - offer_id: str = proto.Field( - proto.STRING, - number=4, - optional=True, - ) - title: str = proto.Field( - proto.STRING, - number=5, - optional=True, - ) - brand: str = proto.Field( - proto.STRING, - number=6, - optional=True, - ) - category_l1: str = proto.Field( - proto.STRING, - number=7, - optional=True, - ) - category_l2: str = proto.Field( - proto.STRING, - number=8, - optional=True, - ) - category_l3: str = proto.Field( - proto.STRING, - number=9, - optional=True, - ) - category_l4: str = proto.Field( - proto.STRING, - number=10, - optional=True, - ) - category_l5: str = proto.Field( - proto.STRING, - number=11, - optional=True, - ) - product_type_l1: str = proto.Field( - proto.STRING, - number=12, - optional=True, - ) - product_type_l2: str = proto.Field( - proto.STRING, - number=13, - optional=True, - ) - product_type_l3: str = proto.Field( - proto.STRING, - number=14, - optional=True, - ) - product_type_l4: str = proto.Field( - proto.STRING, - number=15, - optional=True, - ) - product_type_l5: str = proto.Field( - proto.STRING, - number=16, - optional=True, - ) - price: types.Price = proto.Field( - proto.MESSAGE, - number=17, - message=types.Price, - ) - condition: str = proto.Field( - proto.STRING, - number=18, - optional=True, - ) - availability: str = proto.Field( - proto.STRING, - number=19, - optional=True, - ) - shipping_label: str = proto.Field( - proto.STRING, - number=20, - optional=True, - ) - gtin: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=21, - ) - item_group_id: str = proto.Field( - proto.STRING, - number=22, - optional=True, - ) - thumbnail_link: str = proto.Field( - proto.STRING, - number=23, - optional=True, - ) - creation_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=24, - message=timestamp_pb2.Timestamp, - ) - expiration_date: date_pb2.Date = proto.Field( - proto.MESSAGE, - number=25, - message=date_pb2.Date, - ) - aggregated_reporting_context_status: AggregatedReportingContextStatus = proto.Field( - proto.ENUM, - number=26, - optional=True, - enum=AggregatedReportingContextStatus, - ) - item_issues: MutableSequence[ItemIssue] = proto.RepeatedField( - proto.MESSAGE, - number=27, - message=ItemIssue, - ) - click_potential: ClickPotential = proto.Field( - proto.ENUM, - number=29, - enum=ClickPotential, - ) - click_potential_rank: int = proto.Field( - proto.INT64, - number=30, - optional=True, - ) - - -class PriceCompetitivenessProductView(proto.Message): - r"""Fields available for query in ``price_competitiveness_product_view`` - table. - - `Price - competitiveness `__ - report. - - Values are only set for fields requested explicitly in the request's - search query. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - report_country_code (str): - Country of the price benchmark. Represented in the ISO 3166 - format. - - Required in the ``SELECT`` clause. - - This field is a member of `oneof`_ ``_report_country_code``. - id (str): - REST ID of the product, in the form of - ``channel~languageCode~feedLabel~offerId``. Can be used to - join data with the ``product_view`` table. - - Required in the ``SELECT`` clause. - - This field is a member of `oneof`_ ``_id``. - offer_id (str): - Merchant-provided id of the product. - - This field is a member of `oneof`_ ``_offer_id``. - title (str): - Title of the product. - - This field is a member of `oneof`_ ``_title``. - brand (str): - Brand of the product. - - This field is a member of `oneof`_ ``_brand``. - category_l1 (str): - Product category (1st level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l1``. - category_l2 (str): - Product category (2nd level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l2``. - category_l3 (str): - Product category (3rd level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l3``. - category_l4 (str): - Product category (4th level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l4``. - category_l5 (str): - Product category (5th level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l5``. - product_type_l1 (str): - Product type (1st level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l1``. - product_type_l2 (str): - Product type (2nd level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l2``. - product_type_l3 (str): - Product type (3rd level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l3``. - product_type_l4 (str): - Product type (4th level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l4``. - product_type_l5 (str): - Product type (5th level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l5``. - price (google.shopping.type.types.Price): - Current price of the product. - benchmark_price (google.shopping.type.types.Price): - Latest available price benchmark for the - product's catalog in the benchmark country. - """ - - report_country_code: str = proto.Field( - proto.STRING, - number=1, - optional=True, - ) - id: str = proto.Field( - proto.STRING, - number=2, - optional=True, - ) - offer_id: str = proto.Field( - proto.STRING, - number=3, - optional=True, - ) - title: str = proto.Field( - proto.STRING, - number=4, - optional=True, - ) - brand: str = proto.Field( - proto.STRING, - number=5, - optional=True, - ) - category_l1: str = proto.Field( - proto.STRING, - number=6, - optional=True, - ) - category_l2: str = proto.Field( - proto.STRING, - number=7, - optional=True, - ) - category_l3: str = proto.Field( - proto.STRING, - number=8, - optional=True, - ) - category_l4: str = proto.Field( - proto.STRING, - number=9, - optional=True, - ) - category_l5: str = proto.Field( - proto.STRING, - number=10, - optional=True, - ) - product_type_l1: str = proto.Field( - proto.STRING, - number=11, - optional=True, - ) - product_type_l2: str = proto.Field( - proto.STRING, - number=12, - optional=True, - ) - product_type_l3: str = proto.Field( - proto.STRING, - number=13, - optional=True, - ) - product_type_l4: str = proto.Field( - proto.STRING, - number=14, - optional=True, - ) - product_type_l5: str = proto.Field( - proto.STRING, - number=15, - optional=True, - ) - price: types.Price = proto.Field( - proto.MESSAGE, - number=16, - message=types.Price, - ) - benchmark_price: types.Price = proto.Field( - proto.MESSAGE, - number=17, - message=types.Price, - ) - - -class PriceInsightsProductView(proto.Message): - r"""Fields available for query in ``price_insights_product_view`` table. - - `Price - insights `__ - report. - - Values are only set for fields requested explicitly in the request's - search query. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - id (str): - REST ID of the product, in the form of - ``channel~languageCode~feedLabel~offerId``. Can be used to - join data with the ``product_view`` table. - - Required in the ``SELECT`` clause. - - This field is a member of `oneof`_ ``_id``. - offer_id (str): - Merchant-provided id of the product. - - This field is a member of `oneof`_ ``_offer_id``. - title (str): - Title of the product. - - This field is a member of `oneof`_ ``_title``. - brand (str): - Brand of the product. - - This field is a member of `oneof`_ ``_brand``. - category_l1 (str): - Product category (1st level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l1``. - category_l2 (str): - Product category (2nd level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l2``. - category_l3 (str): - Product category (3rd level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l3``. - category_l4 (str): - Product category (4th level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l4``. - category_l5 (str): - Product category (5th level) in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l5``. - product_type_l1 (str): - Product type (1st level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l1``. - product_type_l2 (str): - Product type (2nd level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l2``. - product_type_l3 (str): - Product type (3rd level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l3``. - product_type_l4 (str): - Product type (4th level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l4``. - product_type_l5 (str): - Product type (5th level) in merchant's own `product - taxonomy `__. - - This field is a member of `oneof`_ ``_product_type_l5``. - price (google.shopping.type.types.Price): - Current price of the product. - suggested_price (google.shopping.type.types.Price): - Latest suggested price for the product. - predicted_impressions_change_fraction (float): - Predicted change in impressions as a fraction - after introducing the suggested price compared - to current active price. For example, 0.05 is a - 5% predicted increase in impressions. - - This field is a member of `oneof`_ ``_predicted_impressions_change_fraction``. - predicted_clicks_change_fraction (float): - Predicted change in clicks as a fraction - after introducing the suggested price compared - to current active price. For example, 0.05 is a - 5% predicted increase in clicks. - - This field is a member of `oneof`_ ``_predicted_clicks_change_fraction``. - predicted_conversions_change_fraction (float): - Predicted change in conversions as a fraction - after introducing the suggested price compared - to current active price. For example, 0.05 is a - 5% predicted increase in conversions). - - This field is a member of `oneof`_ ``_predicted_conversions_change_fraction``. - effectiveness (google.shopping.merchant_reports_v1beta.types.PriceInsightsProductView.Effectiveness): - The predicted effectiveness of applying the - price suggestion, bucketed. - """ - class Effectiveness(proto.Enum): - r"""Predicted effectiveness bucket. - - Effectiveness indicates which products would benefit most from price - changes. This rating takes into consideration the performance boost - predicted by adjusting the sale price and the difference between - your current price and the suggested price. Price suggestions with - ``HIGH`` effectiveness are predicted to drive the largest increase - in performance. - - Values: - EFFECTIVENESS_UNSPECIFIED (0): - Effectiveness is unknown. - LOW (1): - Effectiveness is low. - MEDIUM (2): - Effectiveness is medium. - HIGH (3): - Effectiveness is high. - """ - EFFECTIVENESS_UNSPECIFIED = 0 - LOW = 1 - MEDIUM = 2 - HIGH = 3 - - id: str = proto.Field( - proto.STRING, - number=1, - optional=True, - ) - offer_id: str = proto.Field( - proto.STRING, - number=2, - optional=True, - ) - title: str = proto.Field( - proto.STRING, - number=3, - optional=True, - ) - brand: str = proto.Field( - proto.STRING, - number=4, - optional=True, - ) - category_l1: str = proto.Field( - proto.STRING, - number=5, - optional=True, - ) - category_l2: str = proto.Field( - proto.STRING, - number=6, - optional=True, - ) - category_l3: str = proto.Field( - proto.STRING, - number=7, - optional=True, - ) - category_l4: str = proto.Field( - proto.STRING, - number=8, - optional=True, - ) - category_l5: str = proto.Field( - proto.STRING, - number=9, - optional=True, - ) - product_type_l1: str = proto.Field( - proto.STRING, - number=10, - optional=True, - ) - product_type_l2: str = proto.Field( - proto.STRING, - number=11, - optional=True, - ) - product_type_l3: str = proto.Field( - proto.STRING, - number=12, - optional=True, - ) - product_type_l4: str = proto.Field( - proto.STRING, - number=13, - optional=True, - ) - product_type_l5: str = proto.Field( - proto.STRING, - number=14, - optional=True, - ) - price: types.Price = proto.Field( - proto.MESSAGE, - number=15, - message=types.Price, - ) - suggested_price: types.Price = proto.Field( - proto.MESSAGE, - number=16, - message=types.Price, - ) - predicted_impressions_change_fraction: float = proto.Field( - proto.DOUBLE, - number=17, - optional=True, - ) - predicted_clicks_change_fraction: float = proto.Field( - proto.DOUBLE, - number=18, - optional=True, - ) - predicted_conversions_change_fraction: float = proto.Field( - proto.DOUBLE, - number=19, - optional=True, - ) - effectiveness: Effectiveness = proto.Field( - proto.ENUM, - number=22, - enum=Effectiveness, - ) - - -class BestSellersProductClusterView(proto.Message): - r"""Fields available for query in ``best_sellers_product_cluster_view`` - table. - - `Best - sellers `__ - report with top product clusters. A product cluster is a grouping - for different offers and variants that represent the same product, - for example, Google Pixel 7. - - Values are only set for fields requested explicitly in the request's - search query. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - report_date (google.type.date_pb2.Date): - Report date. The value of this field can only be one of the - following: - - - The first day of the week (Monday) for weekly reports, - - The first day of the month for monthly reports. - - Required in the ``SELECT`` clause. If a ``WHERE`` condition - on ``report_date`` is not specified in the query, the latest - available weekly or monthly report is returned. - report_granularity (google.shopping.merchant_reports_v1beta.types.ReportGranularity.ReportGranularityEnum): - Granularity of the report. The ranking can be done over a - week or a month timeframe. - - Required in the ``SELECT`` clause. Condition on - ``report_granularity`` is required in the ``WHERE`` clause. - - This field is a member of `oneof`_ ``_report_granularity``. - report_country_code (str): - Country where the ranking is calculated. Represented in the - ISO 3166 format. - - Required in the ``SELECT`` clause. Condition on - ``report_country_code`` is required in the ``WHERE`` clause. - - This field is a member of `oneof`_ ``_report_country_code``. - report_category_id (int): - Google product category ID to calculate the ranking for, - represented in `Google's product - taxonomy `__. - - Required in the ``SELECT`` clause. If a ``WHERE`` condition - on ``report_category_id`` is not specified in the query, - rankings for all top-level categories are returned. - - This field is a member of `oneof`_ ``_report_category_id``. - title (str): - Title of the product cluster. - - This field is a member of `oneof`_ ``_title``. - brand (str): - Brand of the product cluster. - - This field is a member of `oneof`_ ``_brand``. - category_l1 (str): - Product category (1st level) of the product cluster, - represented in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l1``. - category_l2 (str): - Product category (2nd level) of the product cluster, - represented in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l2``. - category_l3 (str): - Product category (3rd level) of the product cluster, - represented in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l3``. - category_l4 (str): - Product category (4th level) of the product cluster, - represented in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l4``. - category_l5 (str): - Product category (5th level) of the product cluster, - represented in `Google's product - taxonomy `__. - - This field is a member of `oneof`_ ``_category_l5``. - variant_gtins (MutableSequence[str]): - GTINs of example variants of the product - cluster. - inventory_status (google.shopping.merchant_reports_v1beta.types.BestSellersProductClusterView.InventoryStatus): - Whether the product cluster is ``IN_STOCK`` in your product - data source in at least one of the countries, - ``OUT_OF_STOCK`` in your product data source in all - countries, or ``NOT_IN_INVENTORY`` at all. - - The field doesn't take the Best sellers report country - filter into account. - - This field is a member of `oneof`_ ``_inventory_status``. - brand_inventory_status (google.shopping.merchant_reports_v1beta.types.BestSellersProductClusterView.InventoryStatus): - Whether there is at least one product of the brand currently - ``IN_STOCK`` in your product data source in at least one of - the countries, all products are ``OUT_OF_STOCK`` in your - product data source in all countries, or - ``NOT_IN_INVENTORY``. - - The field doesn't take the Best sellers report country - filter into account. - - This field is a member of `oneof`_ ``_brand_inventory_status``. - rank (int): - Popularity of the product cluster on Ads and - organic surfaces, in the selected category and - country, based on the estimated number of units - sold. - - This field is a member of `oneof`_ ``_rank``. - previous_rank (int): - Popularity rank in the previous week or - month. - - This field is a member of `oneof`_ ``_previous_rank``. - relative_demand (google.shopping.merchant_reports_v1beta.types.RelativeDemand.RelativeDemandEnum): - Estimated demand in relation to the product - cluster with the highest popularity rank in the - same category and country. - - This field is a member of `oneof`_ ``_relative_demand``. - previous_relative_demand (google.shopping.merchant_reports_v1beta.types.RelativeDemand.RelativeDemandEnum): - Estimated demand in relation to the product - cluster with the highest popularity rank in the - same category and country in the previous week - or month. - - This field is a member of `oneof`_ ``_previous_relative_demand``. - relative_demand_change (google.shopping.merchant_reports_v1beta.types.RelativeDemandChangeType.RelativeDemandChangeTypeEnum): - Change in the estimated demand. Whether it - rose, sank or remained flat. - - This field is a member of `oneof`_ ``_relative_demand_change``. - """ - class InventoryStatus(proto.Enum): - r"""Status of the product cluster or brand in your inventory. - - Values: - INVENTORY_STATUS_UNSPECIFIED (0): - Not specified. - IN_STOCK (1): - You have a product for this product cluster - or brand in stock. - OUT_OF_STOCK (2): - You have a product for this product cluster - or brand in inventory but it is currently out of - stock. - NOT_IN_INVENTORY (3): - You do not have a product for this product - cluster or brand in inventory. - """ - INVENTORY_STATUS_UNSPECIFIED = 0 - IN_STOCK = 1 - OUT_OF_STOCK = 2 - NOT_IN_INVENTORY = 3 - - report_date: date_pb2.Date = proto.Field( - proto.MESSAGE, - number=1, - message=date_pb2.Date, - ) - report_granularity: 'ReportGranularity.ReportGranularityEnum' = proto.Field( - proto.ENUM, - number=2, - optional=True, - enum='ReportGranularity.ReportGranularityEnum', - ) - report_country_code: str = proto.Field( - proto.STRING, - number=3, - optional=True, - ) - report_category_id: int = proto.Field( - proto.INT64, - number=4, - optional=True, - ) - title: str = proto.Field( - proto.STRING, - number=6, - optional=True, - ) - brand: str = proto.Field( - proto.STRING, - number=7, - optional=True, - ) - category_l1: str = proto.Field( - proto.STRING, - number=8, - optional=True, - ) - category_l2: str = proto.Field( - proto.STRING, - number=9, - optional=True, - ) - category_l3: str = proto.Field( - proto.STRING, - number=10, - optional=True, - ) - category_l4: str = proto.Field( - proto.STRING, - number=11, - optional=True, - ) - category_l5: str = proto.Field( - proto.STRING, - number=12, - optional=True, - ) - variant_gtins: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=13, - ) - inventory_status: InventoryStatus = proto.Field( - proto.ENUM, - number=14, - optional=True, - enum=InventoryStatus, - ) - brand_inventory_status: InventoryStatus = proto.Field( - proto.ENUM, - number=15, - optional=True, - enum=InventoryStatus, - ) - rank: int = proto.Field( - proto.INT64, - number=16, - optional=True, - ) - previous_rank: int = proto.Field( - proto.INT64, - number=17, - optional=True, - ) - relative_demand: 'RelativeDemand.RelativeDemandEnum' = proto.Field( - proto.ENUM, - number=18, - optional=True, - enum='RelativeDemand.RelativeDemandEnum', - ) - previous_relative_demand: 'RelativeDemand.RelativeDemandEnum' = proto.Field( - proto.ENUM, - number=19, - optional=True, - enum='RelativeDemand.RelativeDemandEnum', - ) - relative_demand_change: 'RelativeDemandChangeType.RelativeDemandChangeTypeEnum' = proto.Field( - proto.ENUM, - number=20, - optional=True, - enum='RelativeDemandChangeType.RelativeDemandChangeTypeEnum', - ) - - -class BestSellersBrandView(proto.Message): - r"""Fields available for query in ``best_sellers_brand_view`` table. - - `Best - sellers `__ - report with top brands. - - Values are only set for fields requested explicitly in the request's - search query. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - report_date (google.type.date_pb2.Date): - Report date. The value of this field can only be one of the - following: - - - The first day of the week (Monday) for weekly reports, - - The first day of the month for monthly reports. - - Required in the ``SELECT`` clause. If a ``WHERE`` condition - on ``report_date`` is not specified in the query, the latest - available weekly or monthly report is returned. - report_granularity (google.shopping.merchant_reports_v1beta.types.ReportGranularity.ReportGranularityEnum): - Granularity of the report. The ranking can be done over a - week or a month timeframe. - - Required in the ``SELECT`` clause. Condition on - ``report_granularity`` is required in the ``WHERE`` clause. - - This field is a member of `oneof`_ ``_report_granularity``. - report_country_code (str): - Country where the ranking is calculated. Represented in the - ISO 3166 format. - - Required in the ``SELECT`` clause. Condition on - ``report_country_code`` is required in the ``WHERE`` clause. - - This field is a member of `oneof`_ ``_report_country_code``. - report_category_id (int): - Google product category ID to calculate the ranking for, - represented in `Google's product - taxonomy `__. - - Required in the ``SELECT`` clause. If a ``WHERE`` condition - on ``report_category_id`` is not specified in the query, - rankings for all top-level categories are returned. - - This field is a member of `oneof`_ ``_report_category_id``. - brand (str): - Name of the brand. - - This field is a member of `oneof`_ ``_brand``. - rank (int): - Popularity of the brand on Ads and organic - surfaces, in the selected category and country, - based on the estimated number of units sold. - - This field is a member of `oneof`_ ``_rank``. - previous_rank (int): - Popularity rank in the previous week or - month. - - This field is a member of `oneof`_ ``_previous_rank``. - relative_demand (google.shopping.merchant_reports_v1beta.types.RelativeDemand.RelativeDemandEnum): - Estimated demand in relation to the brand - with the highest popularity rank in the same - category and country. - - This field is a member of `oneof`_ ``_relative_demand``. - previous_relative_demand (google.shopping.merchant_reports_v1beta.types.RelativeDemand.RelativeDemandEnum): - Estimated demand in relation to the brand - with the highest popularity rank in the same - category and country in the previous week or - month. - - This field is a member of `oneof`_ ``_previous_relative_demand``. - relative_demand_change (google.shopping.merchant_reports_v1beta.types.RelativeDemandChangeType.RelativeDemandChangeTypeEnum): - Change in the estimated demand. Whether it - rose, sank or remained flat. - - This field is a member of `oneof`_ ``_relative_demand_change``. - """ - - report_date: date_pb2.Date = proto.Field( - proto.MESSAGE, - number=1, - message=date_pb2.Date, - ) - report_granularity: 'ReportGranularity.ReportGranularityEnum' = proto.Field( - proto.ENUM, - number=2, - optional=True, - enum='ReportGranularity.ReportGranularityEnum', - ) - report_country_code: str = proto.Field( - proto.STRING, - number=3, - optional=True, - ) - report_category_id: int = proto.Field( - proto.INT64, - number=4, - optional=True, - ) - brand: str = proto.Field( - proto.STRING, - number=6, - optional=True, - ) - rank: int = proto.Field( - proto.INT64, - number=7, - optional=True, - ) - previous_rank: int = proto.Field( - proto.INT64, - number=8, - optional=True, - ) - relative_demand: 'RelativeDemand.RelativeDemandEnum' = proto.Field( - proto.ENUM, - number=9, - optional=True, - enum='RelativeDemand.RelativeDemandEnum', - ) - previous_relative_demand: 'RelativeDemand.RelativeDemandEnum' = proto.Field( - proto.ENUM, - number=10, - optional=True, - enum='RelativeDemand.RelativeDemandEnum', - ) - relative_demand_change: 'RelativeDemandChangeType.RelativeDemandChangeTypeEnum' = proto.Field( - proto.ENUM, - number=11, - optional=True, - enum='RelativeDemandChangeType.RelativeDemandChangeTypeEnum', - ) - - -class NonProductPerformanceView(proto.Message): - r"""Fields available for query in ``non_product_performance_view`` - table. - - Performance data on images and online store links leading to your - non-product pages. This includes performance metrics (for example, - ``clicks``) and dimensions according to which performance metrics - are segmented (for example, ``date``). - - Segment fields cannot be selected in queries without also selecting - at least one metric field. - - Values are only set for fields requested explicitly in the request's - search query. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - date (google.type.date_pb2.Date): - Date in the merchant timezone to which metrics apply. - Segment. - - Condition on ``date`` is required in the ``WHERE`` clause. - week (google.type.date_pb2.Date): - First day of the week (Monday) of the metrics - date in the merchant timezone. Segment. - clicks (int): - Number of clicks on images and online store - links leading to your non-product pages. Metric. - - This field is a member of `oneof`_ ``_clicks``. - impressions (int): - Number of times images and online store links - leading to your non-product pages were shown. - Metric. - - This field is a member of `oneof`_ ``_impressions``. - click_through_rate (float): - Click-through rate - the number of clicks (``clicks``) - divided by the number of impressions (``impressions``) of - images and online store links leading to your non-product - pages. Metric. - - This field is a member of `oneof`_ ``_click_through_rate``. - """ - - date: date_pb2.Date = proto.Field( - proto.MESSAGE, - number=1, - message=date_pb2.Date, - ) - week: date_pb2.Date = proto.Field( - proto.MESSAGE, - number=2, - message=date_pb2.Date, - ) - clicks: int = proto.Field( - proto.INT64, - number=3, - optional=True, - ) - impressions: int = proto.Field( - proto.INT64, - number=4, - optional=True, - ) - click_through_rate: float = proto.Field( - proto.DOUBLE, - number=5, - optional=True, - ) - - -class CompetitiveVisibilityCompetitorView(proto.Message): - r"""Fields available for query in - ``competitive_visibility_competitor_view`` table. - - `Competitive - visibility `__ - report with businesses with similar visibility. - - Values are only set for fields requested explicitly in the request's - search query. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - date (google.type.date_pb2.Date): - Date of this row. - - A condition on ``date`` is required in the ``WHERE`` clause. - domain (str): - Domain of your competitor or your domain, if - 'is_your_domain' is true. - - Required in the ``SELECT`` clause. Cannot be filtered on in - the 'WHERE' clause. - - This field is a member of `oneof`_ ``_domain``. - is_your_domain (bool): - True if this row contains data for your - domain. - Cannot be filtered on in the 'WHERE' clause. - - This field is a member of `oneof`_ ``_is_your_domain``. - report_country_code (str): - Country where impressions appeared. - - Required in the ``SELECT`` clause. A condition on - ``report_country_code`` is required in the ``WHERE`` clause. - - This field is a member of `oneof`_ ``_report_country_code``. - report_category_id (int): - Google product category ID to calculate the report for, - represented in `Google's product - taxonomy `__. - - Required in the ``SELECT`` clause. A condition on - ``report_category_id`` is required in the ``WHERE`` clause. - - This field is a member of `oneof`_ ``_report_category_id``. - traffic_source (google.shopping.merchant_reports_v1beta.types.TrafficSource.TrafficSourceEnum): - Traffic source of impressions. - - Required in the ``SELECT`` clause. - - This field is a member of `oneof`_ ``_traffic_source``. - rank (int): - Position of the domain in the similar businesses ranking for - the selected keys (``date``, ``report_category_id``, - ``report_country_code``, ``traffic_source``) based on - impressions. 1 is the highest. - - Cannot be filtered on in the 'WHERE' clause. - - This field is a member of `oneof`_ ``_rank``. - ads_organic_ratio (float): - [Ads / organic ratio] - (https://support.google.com/merchants/answer/11366442#zippy=%2Cads-free-ratio) - shows how often the domain receives impressions from - Shopping ads compared to organic traffic. The number is - rounded and bucketed. - - Cannot be filtered on in the 'WHERE' clause. - - This field is a member of `oneof`_ ``_ads_organic_ratio``. - page_overlap_rate (float): - [Page overlap rate] - (https://support.google.com/merchants/answer/11366442#zippy=%2Cpage-overlap-rate) - shows how frequently competing retailers’ offers are shown - together with your offers on the same page. - - Cannot be filtered on in the 'WHERE' clause. - - This field is a member of `oneof`_ ``_page_overlap_rate``. - higher_position_rate (float): - [Higher position rate] - (https://support.google.com/merchants/answer/11366442#zippy=%2Chigher-position-rate) - shows how often a competitor’s offer got placed in a higher - position on the page than your offer. - - Cannot be filtered on in the 'WHERE' clause. - - This field is a member of `oneof`_ ``_higher_position_rate``. - relative_visibility (float): - [Relative visibility] - (https://support.google.com/merchants/answer/11366442#zippy=%2Crelative-visibility) - shows how often your competitors’ offers are shown compared - to your offers. In other words, this is the number of - displayed impressions of a competitor retailer divided by - the number of your displayed impressions during a selected - time range for a selected product category and country. - - Cannot be filtered on in the 'WHERE' clause. - - This field is a member of `oneof`_ ``_relative_visibility``. - """ - - date: date_pb2.Date = proto.Field( - proto.MESSAGE, - number=1, - message=date_pb2.Date, - ) - domain: str = proto.Field( - proto.STRING, - number=2, - optional=True, - ) - is_your_domain: bool = proto.Field( - proto.BOOL, - number=3, - optional=True, - ) - report_country_code: str = proto.Field( - proto.STRING, - number=4, - optional=True, - ) - report_category_id: int = proto.Field( - proto.INT64, - number=5, - optional=True, - ) - traffic_source: 'TrafficSource.TrafficSourceEnum' = proto.Field( - proto.ENUM, - number=6, - optional=True, - enum='TrafficSource.TrafficSourceEnum', - ) - rank: int = proto.Field( - proto.INT64, - number=7, - optional=True, - ) - ads_organic_ratio: float = proto.Field( - proto.DOUBLE, - number=8, - optional=True, - ) - page_overlap_rate: float = proto.Field( - proto.DOUBLE, - number=9, - optional=True, - ) - higher_position_rate: float = proto.Field( - proto.DOUBLE, - number=10, - optional=True, - ) - relative_visibility: float = proto.Field( - proto.DOUBLE, - number=11, - optional=True, - ) - - -class CompetitiveVisibilityTopMerchantView(proto.Message): - r"""Fields available for query in - ``competitive_visibility_top_merchant_view`` table. - - `Competitive - visibility `__ - report with business with highest visibility. - - Values are only set for fields requested explicitly in the request's - search query. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - date (google.type.date_pb2.Date): - Date of this row. - - Cannot be selected in the ``SELECT`` clause. A condition on - ``date`` is required in the ``WHERE`` clause. - domain (str): - Domain of your competitor or your domain, if - 'is_your_domain' is true. - - Required in the ``SELECT`` clause. Cannot be filtered on in - the 'WHERE' clause. - - This field is a member of `oneof`_ ``_domain``. - is_your_domain (bool): - True if this row contains data for your - domain. - Cannot be filtered on in the 'WHERE' clause. - - This field is a member of `oneof`_ ``_is_your_domain``. - report_country_code (str): - Country where impressions appeared. - - Required in the ``SELECT`` clause. A condition on - ``report_country_code`` is required in the ``WHERE`` clause. - - This field is a member of `oneof`_ ``_report_country_code``. - report_category_id (int): - Google product category ID to calculate the report for, - represented in `Google's product - taxonomy `__. - - Required in the ``SELECT`` clause. A condition on - ``report_category_id`` is required in the ``WHERE`` clause. - - This field is a member of `oneof`_ ``_report_category_id``. - traffic_source (google.shopping.merchant_reports_v1beta.types.TrafficSource.TrafficSourceEnum): - Traffic source of impressions. - - Required in the ``SELECT`` clause. - - This field is a member of `oneof`_ ``_traffic_source``. - rank (int): - Position of the domain in the top merchants ranking for the - selected keys (``date``, ``report_category_id``, - ``report_country_code``, ``traffic_source``) based on - impressions. 1 is the highest. - - Cannot be filtered on in the 'WHERE' clause. - - This field is a member of `oneof`_ ``_rank``. - ads_organic_ratio (float): - [Ads / organic ratio] - (https://support.google.com/merchants/answer/11366442#zippy=%2Cads-free-ratio) - shows how often the domain receives impressions from - Shopping ads compared to organic traffic. The number is - rounded and bucketed. - - Cannot be filtered on in the 'WHERE' clause. - - This field is a member of `oneof`_ ``_ads_organic_ratio``. - page_overlap_rate (float): - [Page overlap rate] - (https://support.google.com/merchants/answer/11366442#zippy=%2Cpage-overlap-rate) - shows how frequently competing retailers’ offers are shown - together with your offers on the same page. - - Cannot be filtered on in the 'WHERE' clause. - - This field is a member of `oneof`_ ``_page_overlap_rate``. - higher_position_rate (float): - [Higher position rate] - (https://support.google.com/merchants/answer/11366442#zippy=%2Chigher-position-rate) - shows how often a competitor’s offer got placed in a higher - position on the page than your offer. - - Cannot be filtered on in the 'WHERE' clause. - - This field is a member of `oneof`_ ``_higher_position_rate``. - """ - - date: date_pb2.Date = proto.Field( - proto.MESSAGE, - number=1, - message=date_pb2.Date, - ) - domain: str = proto.Field( - proto.STRING, - number=2, - optional=True, - ) - is_your_domain: bool = proto.Field( - proto.BOOL, - number=3, - optional=True, - ) - report_country_code: str = proto.Field( - proto.STRING, - number=4, - optional=True, - ) - report_category_id: int = proto.Field( - proto.INT64, - number=5, - optional=True, - ) - traffic_source: 'TrafficSource.TrafficSourceEnum' = proto.Field( - proto.ENUM, - number=6, - optional=True, - enum='TrafficSource.TrafficSourceEnum', - ) - rank: int = proto.Field( - proto.INT64, - number=7, - optional=True, - ) - ads_organic_ratio: float = proto.Field( - proto.DOUBLE, - number=8, - optional=True, - ) - page_overlap_rate: float = proto.Field( - proto.DOUBLE, - number=9, - optional=True, - ) - higher_position_rate: float = proto.Field( - proto.DOUBLE, - number=10, - optional=True, - ) - - -class CompetitiveVisibilityBenchmarkView(proto.Message): - r"""Fields available for query in - ``competitive_visibility_benchmark_view`` table. - - `Competitive - visibility `__ - report with the category benchmark. - - Values are only set for fields requested explicitly in the request's - search query. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - date (google.type.date_pb2.Date): - Date of this row. - - Required in the ``SELECT`` clause. A condition on ``date`` - is required in the ``WHERE`` clause. - report_country_code (str): - Country where impressions appeared. - - Required in the ``SELECT`` clause. A condition on - ``report_country_code`` is required in the ``WHERE`` clause. - - This field is a member of `oneof`_ ``_report_country_code``. - report_category_id (int): - Google product category ID to calculate the report for, - represented in `Google's product - taxonomy `__. - - Required in the ``SELECT`` clause. A condition on - ``report_category_id`` is required in the ``WHERE`` clause. - - This field is a member of `oneof`_ ``_report_category_id``. - traffic_source (google.shopping.merchant_reports_v1beta.types.TrafficSource.TrafficSourceEnum): - Traffic source of impressions. - - Required in the ``SELECT`` clause. - - This field is a member of `oneof`_ ``_traffic_source``. - your_domain_visibility_trend (float): - Change in visibility based on impressions for - your domain with respect to the start of the - selected time range (or first day with non-zero - impressions). - - Cannot be filtered on in the 'WHERE' clause. - - This field is a member of `oneof`_ ``_your_domain_visibility_trend``. - category_benchmark_visibility_trend (float): - Change in visibility based on impressions - with respect to the start of the selected time - range (or first day with non-zero impressions) - for a combined set of merchants with highest - visibility approximating the market. - - Cannot be filtered on in the 'WHERE' clause. - - This field is a member of `oneof`_ ``_category_benchmark_visibility_trend``. - """ - - date: date_pb2.Date = proto.Field( - proto.MESSAGE, - number=1, - message=date_pb2.Date, - ) - report_country_code: str = proto.Field( - proto.STRING, - number=2, - optional=True, - ) - report_category_id: int = proto.Field( - proto.INT64, - number=3, - optional=True, - ) - traffic_source: 'TrafficSource.TrafficSourceEnum' = proto.Field( - proto.ENUM, - number=4, - optional=True, - enum='TrafficSource.TrafficSourceEnum', - ) - your_domain_visibility_trend: float = proto.Field( - proto.DOUBLE, - number=5, - optional=True, - ) - category_benchmark_visibility_trend: float = proto.Field( - proto.DOUBLE, - number=6, - optional=True, - ) - - -class MarketingMethod(proto.Message): - r"""Marketing method used to promote your products on Google - (organic versus ads). - - """ - class MarketingMethodEnum(proto.Enum): - r"""Marketing method values. - - Values: - MARKETING_METHOD_ENUM_UNSPECIFIED (0): - Not specified. - ORGANIC (1): - Organic marketing. - ADS (2): - Ads-based marketing. - """ - MARKETING_METHOD_ENUM_UNSPECIFIED = 0 - ORGANIC = 1 - ADS = 2 - - -class ReportGranularity(proto.Message): - r"""Granularity of the Best sellers report. Best sellers reports - are computed over a week and a month timeframe. - - """ - class ReportGranularityEnum(proto.Enum): - r"""Report granularity values. - - Values: - REPORT_GRANULARITY_ENUM_UNSPECIFIED (0): - Not specified. - WEEKLY (1): - Report is computed over a week timeframe. - MONTHLY (2): - Report is computed over a month timeframe. - """ - REPORT_GRANULARITY_ENUM_UNSPECIFIED = 0 - WEEKLY = 1 - MONTHLY = 2 - - -class RelativeDemand(proto.Message): - r"""Relative demand of a product cluster or brand in the Best - sellers report. - - """ - class RelativeDemandEnum(proto.Enum): - r"""Relative demand values. - - Values: - RELATIVE_DEMAND_ENUM_UNSPECIFIED (0): - Not specified. - VERY_LOW (10): - Demand is 0-5% of the demand of the highest - ranked product cluster or brand. - LOW (20): - Demand is 6-10% of the demand of the highest - ranked product cluster or brand. - MEDIUM (30): - Demand is 11-20% of the demand of the highest - ranked product cluster or brand. - HIGH (40): - Demand is 21-50% of the demand of the highest - ranked product cluster or brand. - VERY_HIGH (50): - Demand is 51-100% of the demand of the - highest ranked product cluster or brand. - """ - RELATIVE_DEMAND_ENUM_UNSPECIFIED = 0 - VERY_LOW = 10 - LOW = 20 - MEDIUM = 30 - HIGH = 40 - VERY_HIGH = 50 - - -class RelativeDemandChangeType(proto.Message): - r"""Relative demand of a product cluster or brand in the Best - sellers report compared to the previous time period. - - """ - class RelativeDemandChangeTypeEnum(proto.Enum): - r"""Relative demand change type values. - - Values: - RELATIVE_DEMAND_CHANGE_TYPE_ENUM_UNSPECIFIED (0): - Not specified. - SINKER (1): - Relative demand is lower than the previous - time period. - FLAT (2): - Relative demand is equal to the previous time - period. - RISER (3): - Relative demand is higher than the previous - time period. - """ - RELATIVE_DEMAND_CHANGE_TYPE_ENUM_UNSPECIFIED = 0 - SINKER = 1 - FLAT = 2 - RISER = 3 - - -class TrafficSource(proto.Message): - r"""Traffic source of impressions in the Competitive visibility - report. - - """ - class TrafficSourceEnum(proto.Enum): - r"""Traffic source values. - - Values: - TRAFFIC_SOURCE_ENUM_UNSPECIFIED (0): - Not specified. - ORGANIC (1): - Organic traffic. - ADS (2): - Traffic from ads. - ALL (3): - Organic and ads traffic. - """ - TRAFFIC_SOURCE_ENUM_UNSPECIFIED = 0 - ORGANIC = 1 - ADS = 2 - ALL = 3 - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/mypy.ini b/owl-bot-staging/google-shopping-merchant-reports/v1beta/mypy.ini deleted file mode 100644 index 574c5aed394b..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/mypy.ini +++ /dev/null @@ -1,3 +0,0 @@ -[mypy] -python_version = 3.7 -namespace_packages = True diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/noxfile.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/noxfile.py deleted file mode 100644 index da7084b1cfb2..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/noxfile.py +++ /dev/null @@ -1,280 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 re -import shutil -import subprocess -import sys - - -import nox # type: ignore - -ALL_PYTHON = [ - "3.7", - "3.8", - "3.9", - "3.10", - "3.11", - "3.12", - "3.13", -] - -CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() - -LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" -PACKAGE_NAME = 'google-shopping-merchant-reports' - -BLACK_VERSION = "black==22.3.0" -BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] -DEFAULT_PYTHON_VERSION = "3.13" - -nox.sessions = [ - "unit", - "cover", - "mypy", - "check_lower_bounds" - # exclude update_lower_bounds from default - "docs", - "blacken", - "lint", - "prerelease_deps", -] - -@nox.session(python=ALL_PYTHON) -@nox.parametrize( - "protobuf_implementation", - [ "python", "upb", "cpp" ], -) -def unit(session, protobuf_implementation): - """Run the unit test suite.""" - - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): - session.skip("cpp implementation is not supported in python 3.11+") - - session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') - session.install('-e', '.', "-c", f"testing/constraints-{session.python}.txt") - - # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. - # The 'cpp' implementation requires Protobuf<4. - if protobuf_implementation == "cpp": - session.install("protobuf<4") - - session.run( - 'py.test', - '--quiet', - '--cov=google/shopping/merchant_reports_v1beta/', - '--cov=tests/', - '--cov-config=.coveragerc', - '--cov-report=term', - '--cov-report=html', - os.path.join('tests', 'unit', ''.join(session.posargs)), - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - -@nox.session(python=ALL_PYTHON[-1]) -@nox.parametrize( - "protobuf_implementation", - [ "python", "upb", "cpp" ], -) -def prerelease_deps(session, protobuf_implementation): - """Run the unit test suite against pre-release versions of dependencies.""" - - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): - session.skip("cpp implementation is not supported in python 3.11+") - - # Install test environment dependencies - session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') - - # Install the package without dependencies - session.install('-e', '.', '--no-deps') - - # We test the minimum dependency versions using the minimum Python - # version so the lowest python runtime that we test has a corresponding constraints - # file, located at `testing/constraints--.txt`, which contains all of the - # dependencies and extras. - with open( - CURRENT_DIRECTORY - / "testing" - / f"constraints-{ALL_PYTHON[0]}.txt", - encoding="utf-8", - ) as constraints_file: - constraints_text = constraints_file.read() - - # Ignore leading whitespace and comment lines. - constraints_deps = [ - match.group(1) - for match in re.finditer( - r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE - ) - ] - - session.install(*constraints_deps) - - prerel_deps = [ - "googleapis-common-protos", - "google-api-core", - "google-auth", - # Exclude grpcio!=1.67.0rc1 which does not support python 3.13 - "grpcio!=1.67.0rc1", - "grpcio-status", - "protobuf", - "proto-plus", - ] - - for dep in prerel_deps: - session.install("--pre", "--no-deps", "--upgrade", dep) - - # Remaining dependencies - other_deps = [ - "requests", - ] - session.install(*other_deps) - - # Print out prerelease package versions - - session.run("python", "-c", "import google.api_core; print(google.api_core.__version__)") - session.run("python", "-c", "import google.auth; print(google.auth.__version__)") - session.run("python", "-c", "import grpc; print(grpc.__version__)") - session.run( - "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" - ) - session.run( - "python", "-c", "import proto; print(proto.__version__)" - ) - - session.run( - 'py.test', - '--quiet', - '--cov=google/shopping/merchant_reports_v1beta/', - '--cov=tests/', - '--cov-config=.coveragerc', - '--cov-report=term', - '--cov-report=html', - os.path.join('tests', 'unit', ''.join(session.posargs)), - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - - -@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', - '-p', - '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, - ) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_async.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_async.py deleted file mode 100644 index 6fa9200b9512..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_async.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 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-shopping-merchant-reports - - -# [START merchantapi_v1beta_generated_ReportService_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.shopping import merchant_reports_v1beta - - -async def sample_search(): - # Create a client - client = merchant_reports_v1beta.ReportServiceAsyncClient() - - # Initialize request argument(s) - request = merchant_reports_v1beta.SearchRequest( - parent="parent_value", - query="query_value", - ) - - # Make the request - page_result = client.search(request=request) - - # Handle the response - async for response in page_result: - print(response) - -# [END merchantapi_v1beta_generated_ReportService_Search_async] diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_sync.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_sync.py deleted file mode 100644 index 11f591230812..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/merchantapi_v1beta_generated_report_service_search_sync.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 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-shopping-merchant-reports - - -# [START merchantapi_v1beta_generated_ReportService_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.shopping import merchant_reports_v1beta - - -def sample_search(): - # Create a client - client = merchant_reports_v1beta.ReportServiceClient() - - # Initialize request argument(s) - request = merchant_reports_v1beta.SearchRequest( - parent="parent_value", - query="query_value", - ) - - # Make the request - page_result = client.search(request=request) - - # Handle the response - for response in page_result: - print(response) - -# [END merchantapi_v1beta_generated_ReportService_Search_sync] diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1beta.json b/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1beta.json deleted file mode 100644 index 55992b8a05a3..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/samples/generated_samples/snippet_metadata_google.shopping.merchant.reports.v1beta.json +++ /dev/null @@ -1,176 +0,0 @@ -{ - "clientLibrary": { - "apis": [ - { - "id": "google.shopping.merchant.reports.v1beta", - "version": "v1beta" - } - ], - "language": "PYTHON", - "name": "google-shopping-merchant-reports", - "version": "0.1.0" - }, - "snippets": [ - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.shopping.merchant_reports_v1beta.ReportServiceAsyncClient", - "shortName": "ReportServiceAsyncClient" - }, - "fullName": "google.shopping.merchant_reports_v1beta.ReportServiceAsyncClient.search", - "method": { - "fullName": "google.shopping.merchant.reports.v1beta.ReportService.Search", - "service": { - "fullName": "google.shopping.merchant.reports.v1beta.ReportService", - "shortName": "ReportService" - }, - "shortName": "Search" - }, - "parameters": [ - { - "name": "request", - "type": "google.shopping.merchant_reports_v1beta.types.SearchRequest" - }, - { - "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.shopping.merchant_reports_v1beta.services.report_service.pagers.SearchAsyncPager", - "shortName": "search" - }, - "description": "Sample for Search", - "file": "merchantapi_v1beta_generated_report_service_search_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "merchantapi_v1beta_generated_ReportService_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": "merchantapi_v1beta_generated_report_service_search_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.shopping.merchant_reports_v1beta.ReportServiceClient", - "shortName": "ReportServiceClient" - }, - "fullName": "google.shopping.merchant_reports_v1beta.ReportServiceClient.search", - "method": { - "fullName": "google.shopping.merchant.reports.v1beta.ReportService.Search", - "service": { - "fullName": "google.shopping.merchant.reports.v1beta.ReportService", - "shortName": "ReportService" - }, - "shortName": "Search" - }, - "parameters": [ - { - "name": "request", - "type": "google.shopping.merchant_reports_v1beta.types.SearchRequest" - }, - { - "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.shopping.merchant_reports_v1beta.services.report_service.pagers.SearchPager", - "shortName": "search" - }, - "description": "Sample for Search", - "file": "merchantapi_v1beta_generated_report_service_search_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "merchantapi_v1beta_generated_ReportService_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": "merchantapi_v1beta_generated_report_service_search_sync.py" - } - ] -} diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/scripts/fixup_merchant_reports_v1beta_keywords.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/scripts/fixup_merchant_reports_v1beta_keywords.py deleted file mode 100644 index 83db92c96848..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/scripts/fixup_merchant_reports_v1beta_keywords.py +++ /dev/null @@ -1,176 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 merchant_reportsCallTransformer(cst.CSTTransformer): - CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') - METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { - 'search': ('parent', 'query', 'page_size', 'page_token', ), - } - - 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=merchant_reportsCallTransformer(), -): - """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 merchant_reports 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/google-shopping-merchant-reports/v1beta/setup.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/setup.py deleted file mode 100644 index 434b659ca76d..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/setup.py +++ /dev/null @@ -1,99 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 re - -import setuptools # type: ignore - -package_root = os.path.abspath(os.path.dirname(__file__)) - -name = 'google-shopping-merchant-reports' - - -description = "Google Shopping Merchant Reports API client library" - -version = None - -with open(os.path.join(package_root, 'google/shopping/merchant_reports/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) - assert (len(version_candidates) == 1) - version = version_candidates[0] - -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.1, <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.*", - # Exclude incompatible versions of `google-auth` - # See https://github.com/googleapis/google-cloud-python/issues/12364 - "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", - "proto-plus >= 1.22.3, <2.0.0dev", - "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", - "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", - "google-shopping-type >= 0.1.6, <1.0.0dev", -] -extras = { -} -url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-merchant-reports" - -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.find_namespace_packages() - if package.startswith("google") -] - -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", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Operating System :: OS Independent", - "Topic :: Internet", - ], - platforms="Posix; MacOS X; Windows", - packages=packages, - python_requires=">=3.7", - install_requires=dependencies, - extras_require=extras, - include_package_data=True, - zip_safe=False, -) diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.10.txt b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.10.txt deleted file mode 100644 index 4cae520d02b2..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.10.txt +++ /dev/null @@ -1,7 +0,0 @@ -# -*- 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 -google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.11.txt b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.11.txt deleted file mode 100644 index 4cae520d02b2..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.11.txt +++ /dev/null @@ -1,7 +0,0 @@ -# -*- 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 -google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.12.txt b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.12.txt deleted file mode 100644 index 4cae520d02b2..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.12.txt +++ /dev/null @@ -1,7 +0,0 @@ -# -*- 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 -google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.7.txt b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.7.txt deleted file mode 100644 index 130a0c0f80ab..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.7.txt +++ /dev/null @@ -1,11 +0,0 @@ -# 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.1 -google-auth==2.14.1 -proto-plus==1.22.3 -protobuf==3.20.2 -google-shopping-type==0.1.6 diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.8.txt b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.8.txt deleted file mode 100644 index 4cae520d02b2..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.8.txt +++ /dev/null @@ -1,7 +0,0 @@ -# -*- 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 -google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.9.txt b/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.9.txt deleted file mode 100644 index 4cae520d02b2..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.9.txt +++ /dev/null @@ -1,7 +0,0 @@ -# -*- 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 -google-shopping-type diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-reports/v1beta/tests/unit/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-reports/v1beta/tests/unit/gapic/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/__init__.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py b/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py deleted file mode 100644 index 16d4b4d11c0d..000000000000 --- a/owl-bot-staging/google-shopping-merchant-reports/v1beta/tests/unit/gapic/merchant_reports_v1beta/test_report_service.py +++ /dev/null @@ -1,2389 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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, AsyncIterable -from google.protobuf import json_format -import json -import math -import pytest -from google.api_core import api_core_version -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 - -try: - from google.auth.aio import credentials as ga_credentials_async - HAS_GOOGLE_AUTH_AIO = True -except ImportError: # pragma: NO COVER - HAS_GOOGLE_AUTH_AIO = False - -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.api_core import retry as retries -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account -from google.shopping.merchant_reports_v1beta.services.report_service import ReportServiceAsyncClient -from google.shopping.merchant_reports_v1beta.services.report_service import ReportServiceClient -from google.shopping.merchant_reports_v1beta.services.report_service import pagers -from google.shopping.merchant_reports_v1beta.services.report_service import transports -from google.shopping.merchant_reports_v1beta.types import reports -import google.auth - - -async def mock_async_gen(data, chunk_size=1): - for i in range(0, len(data)): # pragma: NO COVER - chunk = data[i : i + chunk_size] - yield chunk.encode("utf-8") - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - -# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. -# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. -def async_anonymous_credentials(): - if HAS_GOOGLE_AUTH_AIO: - return ga_credentials_async.AnonymousCredentials() - return ga_credentials.AnonymousCredentials() - -# 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 - -# If default endpoint template is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint template so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint_template(client): - return "test.{UNIVERSE_DOMAIN}" if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) else client._DEFAULT_ENDPOINT_TEMPLATE - - -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 ReportServiceClient._get_default_mtls_endpoint(None) is None - assert ReportServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint - assert ReportServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint - assert ReportServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint - assert ReportServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint - assert ReportServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - -def test__read_environment_variables(): - assert ReportServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert ReportServiceClient._read_environment_variables() == (True, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - assert ReportServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError) as excinfo: - ReportServiceClient._read_environment_variables() - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - assert ReportServiceClient._read_environment_variables() == (False, "never", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - assert ReportServiceClient._read_environment_variables() == (False, "always", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): - assert ReportServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - ReportServiceClient._read_environment_variables() - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): - assert ReportServiceClient._read_environment_variables() == (False, "auto", "foo.com") - -def test__get_client_cert_source(): - mock_provided_cert_source = mock.Mock() - mock_default_cert_source = mock.Mock() - - assert ReportServiceClient._get_client_cert_source(None, False) is None - assert ReportServiceClient._get_client_cert_source(mock_provided_cert_source, False) is None - assert ReportServiceClient._get_client_cert_source(mock_provided_cert_source, True) == mock_provided_cert_source - - 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_default_cert_source): - assert ReportServiceClient._get_client_cert_source(None, True) is mock_default_cert_source - assert ReportServiceClient._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source - -@mock.patch.object(ReportServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceClient)) -@mock.patch.object(ReportServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceAsyncClient)) -def test__get_api_endpoint(): - api_override = "foo.com" - mock_client_cert_source = mock.Mock() - default_universe = ReportServiceClient._DEFAULT_UNIVERSE - default_endpoint = ReportServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) - mock_universe = "bar.com" - mock_endpoint = ReportServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) - - assert ReportServiceClient._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override - assert ReportServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == ReportServiceClient.DEFAULT_MTLS_ENDPOINT - assert ReportServiceClient._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint - assert ReportServiceClient._get_api_endpoint(None, None, default_universe, "always") == ReportServiceClient.DEFAULT_MTLS_ENDPOINT - assert ReportServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == ReportServiceClient.DEFAULT_MTLS_ENDPOINT - assert ReportServiceClient._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint - assert ReportServiceClient._get_api_endpoint(None, None, default_universe, "never") == default_endpoint - - with pytest.raises(MutualTLSChannelError) as excinfo: - ReportServiceClient._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto") - assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com." - - -def test__get_universe_domain(): - client_universe_domain = "foo.com" - universe_domain_env = "bar.com" - - assert ReportServiceClient._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain - assert ReportServiceClient._get_universe_domain(None, universe_domain_env) == universe_domain_env - assert ReportServiceClient._get_universe_domain(None, None) == ReportServiceClient._DEFAULT_UNIVERSE - - with pytest.raises(ValueError) as excinfo: - ReportServiceClient._get_universe_domain("", None) - assert str(excinfo.value) == "Universe Domain cannot be an empty string." - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc"), - (ReportServiceClient, transports.ReportServiceRestTransport, "rest"), -]) -def test__validate_universe_domain(client_class, transport_class, transport_name): - client = client_class( - transport=transport_class( - credentials=ga_credentials.AnonymousCredentials() - ) - ) - assert client._validate_universe_domain() == True - - # Test the case when universe is already validated. - assert client._validate_universe_domain() == True - - if transport_name == "grpc": - # Test the case where credentials are provided by the - # `local_channel_credentials`. The default universes in both match. - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - client = client_class(transport=transport_class(channel=channel)) - assert client._validate_universe_domain() == True - - # Test the case where credentials do not exist: e.g. a transport is provided - # with no credentials. Validation should still succeed because there is no - # mismatch with non-existent credentials. - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - transport=transport_class(channel=channel) - transport._credentials = None - client = client_class(transport=transport) - assert client._validate_universe_domain() == True - - # TODO: This is needed to cater for older versions of google-auth - # Make this test unconditional once the minimum supported version of - # google-auth becomes 2.23.0 or higher. - google_auth_major, google_auth_minor = [int(part) for part in google.auth.__version__.split(".")[0:2]] - if google_auth_major > 2 or (google_auth_major == 2 and google_auth_minor >= 23): - credentials = ga_credentials.AnonymousCredentials() - credentials._universe_domain = "foo.com" - # Test the case when there is a universe mismatch from the credentials. - client = client_class( - transport=transport_class(credentials=credentials) - ) - with pytest.raises(ValueError) as excinfo: - client._validate_universe_domain() - assert str(excinfo.value) == "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (foo.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." - - # Test the case when there is a universe mismatch from the client. - # - # TODO: Make this test unconditional once the minimum supported version of - # google-api-core becomes 2.15.0 or higher. - api_core_major, api_core_minor = [int(part) for part in api_core_version.__version__.split(".")[0:2]] - if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 15): - client = client_class(client_options={"universe_domain": "bar.com"}, transport=transport_class(credentials=ga_credentials.AnonymousCredentials(),)) - with pytest.raises(ValueError) as excinfo: - client._validate_universe_domain() - assert str(excinfo.value) == "The configured universe domain (bar.com) does not match the universe domain found in the credentials (googleapis.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." - - # Test that ValueError is raised if universe_domain is provided via client options and credentials is None - with pytest.raises(ValueError): - client._compare_universes("foo.bar", None) - - -@pytest.mark.parametrize("client_class,transport_name", [ - (ReportServiceClient, "grpc"), - (ReportServiceAsyncClient, "grpc_asyncio"), - (ReportServiceClient, "rest"), -]) -def test_report_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 == ( - 'merchantapi.googleapis.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else - 'https://merchantapi.googleapis.com' - ) - - -@pytest.mark.parametrize("transport_class,transport_name", [ - (transports.ReportServiceGrpcTransport, "grpc"), - (transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (transports.ReportServiceRestTransport, "rest"), -]) -def test_report_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", [ - (ReportServiceClient, "grpc"), - (ReportServiceAsyncClient, "grpc_asyncio"), - (ReportServiceClient, "rest"), -]) -def test_report_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 == ( - 'merchantapi.googleapis.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else - 'https://merchantapi.googleapis.com' - ) - - -def test_report_service_client_get_transport_class(): - transport = ReportServiceClient.get_transport_class() - available_transports = [ - transports.ReportServiceGrpcTransport, - transports.ReportServiceRestTransport, - ] - assert transport in available_transports - - transport = ReportServiceClient.get_transport_class("grpc") - assert transport == transports.ReportServiceGrpcTransport - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc"), - (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (ReportServiceClient, transports.ReportServiceRestTransport, "rest"), -]) -@mock.patch.object(ReportServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceClient)) -@mock.patch.object(ReportServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceAsyncClient)) -def test_report_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(ReportServiceClient, '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(ReportServiceClient, '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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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) as excinfo: - client = client_class(transport=transport_name) - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - # 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) as excinfo: - client = client_class(transport=transport_name) - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - - # 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - 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", [ - (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc", "true"), - (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), - (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc", "false"), - (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), - (ReportServiceClient, transports.ReportServiceRestTransport, "rest", "true"), - (ReportServiceClient, transports.ReportServiceRestTransport, "rest", "false"), -]) -@mock.patch.object(ReportServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceClient)) -@mock.patch.object(ReportServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceAsyncClient)) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_report_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) - 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) - 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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", [ - ReportServiceClient, ReportServiceAsyncClient -]) -@mock.patch.object(ReportServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ReportServiceClient)) -@mock.patch.object(ReportServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ReportServiceAsyncClient)) -def test_report_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 - - # 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) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - # 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) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - -@pytest.mark.parametrize("client_class", [ - ReportServiceClient, ReportServiceAsyncClient -]) -@mock.patch.object(ReportServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceClient)) -@mock.patch.object(ReportServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(ReportServiceAsyncClient)) -def test_report_service_client_client_api_endpoint(client_class): - mock_client_cert_source = client_cert_source_callback - api_override = "foo.com" - default_universe = ReportServiceClient._DEFAULT_UNIVERSE - default_endpoint = ReportServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) - mock_universe = "bar.com" - mock_endpoint = ReportServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) - - # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", - # use ClientOptions.api_endpoint as the api endpoint regardless. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel"): - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=api_override) - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == api_override - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", - # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - - # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), - # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, - # and ClientOptions.universe_domain="bar.com", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. - options = client_options.ClientOptions() - universe_exists = hasattr(options, "universe_domain") - if universe_exists: - options = client_options.ClientOptions(universe_domain=mock_universe) - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - else: - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == (mock_endpoint if universe_exists else default_endpoint) - assert client.universe_domain == (mock_universe if universe_exists else default_universe) - - # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - options = client_options.ClientOptions() - if hasattr(options, "universe_domain"): - delattr(options, "universe_domain") - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc"), - (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (ReportServiceClient, transports.ReportServiceRestTransport, "rest"), -]) -def test_report_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - 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", [ - (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc", grpc_helpers), - (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), - (ReportServiceClient, transports.ReportServiceRestTransport, "rest", None), -]) -def test_report_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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_report_service_client_client_options_from_dict(): - with mock.patch('google.shopping.merchant_reports_v1beta.services.report_service.transports.ReportServiceGrpcTransport.__init__') as grpc_transport: - grpc_transport.return_value = None - client = ReportServiceClient( - 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", [ - (ReportServiceClient, transports.ReportServiceGrpcTransport, "grpc", grpc_helpers), - (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), -]) -def test_report_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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( - "merchantapi.googleapis.com:443", - credentials=file_creds, - credentials_file=None, - quota_project_id=None, - default_scopes=( - 'https://www.googleapis.com/auth/content', -), - scopes=None, - default_host="merchantapi.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("request_type", [ - reports.SearchRequest, - dict, -]) -def test_search(request_type, transport: str = 'grpc'): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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 = reports.SearchResponse( - next_page_token='next_page_token_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] - request = reports.SearchRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.SearchPager) - assert response.next_page_token == 'next_page_token_value' - - -def test_search_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = reports.SearchRequest( - parent='parent_value', - query='query_value', - page_token='page_token_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.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.search(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == reports.SearchRequest( - parent='parent_value', - query='query_value', - page_token='page_token_value', - ) - -def test_search_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.search in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.search] = mock_rpc - request = {} - client.search(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.search(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_search_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = ReportServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.search in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.search] = mock_rpc - - request = {} - await client.search(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.search(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_search_async(transport: str = 'grpc_asyncio', request_type=reports.SearchRequest): - client = ReportServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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(reports.SearchResponse( - next_page_token='next_page_token_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] - request = reports.SearchRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.SearchAsyncPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.asyncio -async def test_search_async_from_dict(): - await test_search_async(request_type=dict) - -def test_search_field_headers(): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = reports.SearchRequest() - - request.parent = 'parent_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 = reports.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', - 'parent=parent_value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_search_field_headers_async(): - client = ReportServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = reports.SearchRequest() - - request.parent = 'parent_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(reports.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', - 'parent=parent_value', - ) in kw['metadata'] - - -def test_search_flattened(): - client = ReportServiceClient( - 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__') as call: - # Designate an appropriate return value for the call. - call.return_value = reports.SearchResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.search( - 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_search_flattened_error(): - client = ReportServiceClient( - 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.search( - reports.SearchRequest(), - parent='parent_value', - ) - -@pytest.mark.asyncio -async def test_search_flattened_async(): - client = ReportServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # 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 = reports.SearchResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(reports.SearchResponse()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.search( - 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_search_flattened_error_async(): - client = ReportServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.search( - reports.SearchRequest(), - parent='parent_value', - ) - - -def test_search_pager(transport_name: str = "grpc"): - client = ReportServiceClient( - 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 = ( - reports.SearchResponse( - results=[ - reports.ReportRow(), - reports.ReportRow(), - reports.ReportRow(), - ], - next_page_token='abc', - ), - reports.SearchResponse( - results=[], - next_page_token='def', - ), - reports.SearchResponse( - results=[ - reports.ReportRow(), - ], - next_page_token='ghi', - ), - reports.SearchResponse( - results=[ - reports.ReportRow(), - reports.ReportRow(), - ], - ), - RuntimeError, - ) - - expected_metadata = () - retry = retries.Retry() - timeout = 5 - expected_metadata = tuple(expected_metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ('parent', ''), - )), - ) - pager = client.search(request={}, retry=retry, timeout=timeout) - - assert pager._metadata == expected_metadata - assert pager._retry == retry - assert pager._timeout == timeout - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, reports.ReportRow) - for i in results) -def test_search_pages(transport_name: str = "grpc"): - client = ReportServiceClient( - 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 = ( - reports.SearchResponse( - results=[ - reports.ReportRow(), - reports.ReportRow(), - reports.ReportRow(), - ], - next_page_token='abc', - ), - reports.SearchResponse( - results=[], - next_page_token='def', - ), - reports.SearchResponse( - results=[ - reports.ReportRow(), - ], - next_page_token='ghi', - ), - reports.SearchResponse( - results=[ - reports.ReportRow(), - reports.ReportRow(), - ], - ), - 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 = ReportServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # 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 = ( - reports.SearchResponse( - results=[ - reports.ReportRow(), - reports.ReportRow(), - reports.ReportRow(), - ], - next_page_token='abc', - ), - reports.SearchResponse( - results=[], - next_page_token='def', - ), - reports.SearchResponse( - results=[ - reports.ReportRow(), - ], - next_page_token='ghi', - ), - reports.SearchResponse( - results=[ - reports.ReportRow(), - reports.ReportRow(), - ], - ), - 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, reports.ReportRow) - for i in responses) - - -@pytest.mark.asyncio -async def test_search_async_pages(): - client = ReportServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # 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 = ( - reports.SearchResponse( - results=[ - reports.ReportRow(), - reports.ReportRow(), - reports.ReportRow(), - ], - next_page_token='abc', - ), - reports.SearchResponse( - results=[], - next_page_token='def', - ), - reports.SearchResponse( - results=[ - reports.ReportRow(), - ], - next_page_token='ghi', - ), - reports.SearchResponse( - results=[ - reports.ReportRow(), - reports.ReportRow(), - ], - ), - 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 - - -def test_search_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.search in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.search] = mock_rpc - - request = {} - client.search(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.search(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_search_rest_required_fields(request_type=reports.SearchRequest): - transport_class = transports.ReportServiceRestTransport - - request_init = {} - request_init["parent"] = "" - request_init["query"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads(json_format.MessageToJson( - pb_request, - 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["parent"] = 'parent_value' - jsonified_request["query"] = 'query_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 "parent" in jsonified_request - assert jsonified_request["parent"] == 'parent_value' - assert "query" in jsonified_request - assert jsonified_request["query"] == 'query_value' - - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = reports.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 - - # Convert return value to protobuf type - return_value = reports.SearchResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.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.ReportServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.search._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("parent", "query", ))) - - -def test_search_rest_flattened(): - client = ReportServiceClient( - 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 = reports.SearchResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {'parent': 'accounts/sample1'} - - # get truthy value for each flattened field - mock_args = dict( - parent='parent_value', - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = reports.SearchResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.search(**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/reports/v1beta/{parent=accounts/*}/reports:search" % client.transport._host, args[1]) - - -def test_search_rest_flattened_error(transport: str = 'rest'): - client = ReportServiceClient( - 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.search( - reports.SearchRequest(), - parent='parent_value', - ) - - -def test_search_rest_pager(transport: str = 'rest'): - client = ReportServiceClient( - 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 = ( - reports.SearchResponse( - results=[ - reports.ReportRow(), - reports.ReportRow(), - reports.ReportRow(), - ], - next_page_token='abc', - ), - reports.SearchResponse( - results=[], - next_page_token='def', - ), - reports.SearchResponse( - results=[ - reports.ReportRow(), - ], - next_page_token='ghi', - ), - reports.SearchResponse( - results=[ - reports.ReportRow(), - reports.ReportRow(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(reports.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 = {'parent': 'accounts/sample1'} - - pager = client.search(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, reports.ReportRow) - 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.ReportServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.ReportServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ReportServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.ReportServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ReportServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ReportServiceClient( - client_options=options, - credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.ReportServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ReportServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.ReportServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = ReportServiceClient(transport=transport) - assert client.transport is transport - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.ReportServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.ReportServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize("transport_class", [ - transports.ReportServiceGrpcTransport, - transports.ReportServiceGrpcAsyncIOTransport, - transports.ReportServiceRestTransport, -]) -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() - -def test_transport_kind_grpc(): - transport = ReportServiceClient.get_transport_class("grpc")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "grpc" - - -def test_initialize_client_w_grpc(): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_search_empty_call_grpc(): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.search), - '__call__') as call: - call.return_value = reports.SearchResponse() - client.search(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = reports.SearchRequest() - - assert args[0] == request_msg - - -def test_transport_kind_grpc_asyncio(): - transport = ReportServiceAsyncClient.get_transport_class("grpc_asyncio")( - credentials=async_anonymous_credentials() - ) - assert transport.kind == "grpc_asyncio" - - -def test_initialize_client_w_grpc_asyncio(): - client = ReportServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_search_empty_call_grpc_asyncio(): - client = ReportServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, 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(reports.SearchResponse( - next_page_token='next_page_token_value', - )) - await client.search(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = reports.SearchRequest() - - assert args[0] == request_msg - - -def test_transport_kind_rest(): - transport = ReportServiceClient.get_transport_class("rest")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "rest" - - -def test_search_rest_bad_request(request_type=reports.SearchRequest): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'parent': 'accounts/sample1'} - 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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.search(request) - - -@pytest.mark.parametrize("request_type", [ - reports.SearchRequest, - dict, -]) -def test_search_rest_call_success(request_type): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'parent': 'accounts/sample1'} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), 'request') as req: - # Designate an appropriate value for the returned response. - return_value = reports.SearchResponse( - next_page_token='next_page_token_value', - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = reports.SearchResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.search(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.SearchPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_search_rest_interceptors(null_interceptor): - transport = transports.ReportServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.ReportServiceRestInterceptor(), - ) - client = ReportServiceClient(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.ReportServiceRestInterceptor, "post_search") as post, \ - mock.patch.object(transports.ReportServiceRestInterceptor, "pre_search") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = reports.SearchRequest.pb(reports.SearchRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = reports.SearchResponse.to_json(reports.SearchResponse()) - req.return_value.content = return_value - - request = reports.SearchRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = reports.SearchResponse() - - client.search(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - -def test_initialize_client_w_rest(): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_search_empty_call_rest(): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.search), - '__call__') as call: - client.search(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = reports.SearchRequest() - - assert args[0] == request_msg - - -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert isinstance( - client.transport, - transports.ReportServiceGrpcTransport, - ) - -def test_report_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.ReportServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json" - ) - - -def test_report_service_base_transport(): - # Instantiate the base transport. - with mock.patch('google.shopping.merchant_reports_v1beta.services.report_service.transports.ReportServiceTransport.__init__') as Transport: - Transport.return_value = None - transport = transports.ReportServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - 'search', - ) - 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_report_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.shopping.merchant_reports_v1beta.services.report_service.transports.ReportServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ReportServiceTransport( - 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/content', -), - quota_project_id="octopus", - ) - - -def test_report_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.shopping.merchant_reports_v1beta.services.report_service.transports.ReportServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ReportServiceTransport() - adc.assert_called_once() - - -def test_report_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) - ReportServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=( - 'https://www.googleapis.com/auth/content', -), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ReportServiceGrpcTransport, - transports.ReportServiceGrpcAsyncIOTransport, - ], -) -def test_report_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/content',), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ReportServiceGrpcTransport, - transports.ReportServiceGrpcAsyncIOTransport, - transports.ReportServiceRestTransport, - ], -) -def test_report_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.ReportServiceGrpcTransport, grpc_helpers), - (transports.ReportServiceGrpcAsyncIOTransport, grpc_helpers_async) - ], -) -def test_report_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( - "merchantapi.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=( - 'https://www.googleapis.com/auth/content', -), - scopes=["1", "2"], - default_host="merchantapi.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("transport_class", [transports.ReportServiceGrpcTransport, transports.ReportServiceGrpcAsyncIOTransport]) -def test_report_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_report_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.ReportServiceRestTransport ( - 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_report_service_host_no_port(transport_name): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='merchantapi.googleapis.com'), - transport=transport_name, - ) - assert client.transport._host == ( - 'merchantapi.googleapis.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else 'https://merchantapi.googleapis.com' - ) - -@pytest.mark.parametrize("transport_name", [ - "grpc", - "grpc_asyncio", - "rest", -]) -def test_report_service_host_with_port(transport_name): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='merchantapi.googleapis.com:8000'), - transport=transport_name, - ) - assert client.transport._host == ( - 'merchantapi.googleapis.com:8000' - if transport_name in ['grpc', 'grpc_asyncio'] - else 'https://merchantapi.googleapis.com:8000' - ) - -@pytest.mark.parametrize("transport_name", [ - "rest", -]) -def test_report_service_client_transport_session_collision(transport_name): - creds1 = ga_credentials.AnonymousCredentials() - creds2 = ga_credentials.AnonymousCredentials() - client1 = ReportServiceClient( - credentials=creds1, - transport=transport_name, - ) - client2 = ReportServiceClient( - credentials=creds2, - transport=transport_name, - ) - session1 = client1.transport.search._session - session2 = client2.transport.search._session - assert session1 != session2 -def test_report_service_grpc_transport_channel(): - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.ReportServiceGrpcTransport( - 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_report_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.ReportServiceGrpcAsyncIOTransport( - 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.ReportServiceGrpcTransport, transports.ReportServiceGrpcAsyncIOTransport]) -def test_report_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.ReportServiceGrpcTransport, transports.ReportServiceGrpcAsyncIOTransport]) -def test_report_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_common_billing_account_path(): - billing_account = "squid" - expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - actual = ReportServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "clam", - } - path = ReportServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = ReportServiceClient.parse_common_billing_account_path(path) - assert expected == actual - -def test_common_folder_path(): - folder = "whelk" - expected = "folders/{folder}".format(folder=folder, ) - actual = ReportServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "octopus", - } - path = ReportServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = ReportServiceClient.parse_common_folder_path(path) - assert expected == actual - -def test_common_organization_path(): - organization = "oyster" - expected = "organizations/{organization}".format(organization=organization, ) - actual = ReportServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "nudibranch", - } - path = ReportServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = ReportServiceClient.parse_common_organization_path(path) - assert expected == actual - -def test_common_project_path(): - project = "cuttlefish" - expected = "projects/{project}".format(project=project, ) - actual = ReportServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "mussel", - } - path = ReportServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = ReportServiceClient.parse_common_project_path(path) - assert expected == actual - -def test_common_location_path(): - project = "winkle" - location = "nautilus" - expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) - actual = ReportServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "scallop", - "location": "abalone", - } - path = ReportServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = ReportServiceClient.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.ReportServiceTransport, '_prep_wrapped_messages') as prep: - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object(transports.ReportServiceTransport, '_prep_wrapped_messages') as prep: - transport_class = ReportServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -def test_transport_close_grpc(): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc" - ) - with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -@pytest.mark.asyncio -async def test_transport_close_grpc_asyncio(): - client = ReportServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio" - ) - with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: - async with client: - close.assert_not_called() - close.assert_called_once() - - -def test_transport_close_rest(): - client = ReportServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - with mock.patch.object(type(getattr(client.transport, "_session")), "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 = ReportServiceClient( - 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", [ - (ReportServiceClient, transports.ReportServiceGrpcTransport), - (ReportServiceAsyncClient, transports.ReportServiceGrpcAsyncIOTransport), -]) -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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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/google-shopping-type/google-shopping-type-py/.coveragerc b/owl-bot-staging/google-shopping-type/google-shopping-type-py/.coveragerc deleted file mode 100644 index 00a864f27048..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/.coveragerc +++ /dev/null @@ -1,13 +0,0 @@ -[run] -branch = True - -[report] -show_missing = True -omit = - google/shopping/type/__init__.py - google/shopping/type/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/google-shopping-type/google-shopping-type-py/.flake8 b/owl-bot-staging/google-shopping-type/google-shopping-type-py/.flake8 deleted file mode 100644 index 29227d4cf419..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/.flake8 +++ /dev/null @@ -1,33 +0,0 @@ -# -*- 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/google-shopping-type/google-shopping-type-py/MANIFEST.in b/owl-bot-staging/google-shopping-type/google-shopping-type-py/MANIFEST.in deleted file mode 100644 index d7887f950009..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -recursive-include google/shopping/type *.py -recursive-include google/shopping/type *.py diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/README.rst b/owl-bot-staging/google-shopping-type/google-shopping-type-py/README.rst deleted file mode 100644 index ad987a05fd48..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/README.rst +++ /dev/null @@ -1,49 +0,0 @@ -Python Client for Google Shopping Type 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 Shopping Type 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/google-shopping-type/google-shopping-type-py/docs/_static/custom.css b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/_static/custom.css deleted file mode 100644 index 06423be0b592..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/_static/custom.css +++ /dev/null @@ -1,3 +0,0 @@ -dl.field-list > dt { - min-width: 100px -} diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/conf.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/conf.py deleted file mode 100644 index ae5cf46489f7..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/conf.py +++ /dev/null @@ -1,376 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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-shopping-type 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-shopping-type" -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 Shopping 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-shopping-type-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-shopping-type.tex", - u"google-shopping-type 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-shopping-type", - u"Google Shopping Type 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-shopping-type", - u"google-shopping-type Documentation", - author, - "google-shopping-type", - "GAPIC library for Google Shopping Type 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/google-shopping-type/google-shopping-type-py/docs/index.rst b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/index.rst deleted file mode 100644 index 2605a730d688..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/index.rst +++ /dev/null @@ -1,7 +0,0 @@ -API Reference -------------- -.. toctree:: - :maxdepth: 2 - - type/services_ - type/types_ diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/services_.rst b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/services_.rst deleted file mode 100644 index 064d8549804a..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/services_.rst +++ /dev/null @@ -1,4 +0,0 @@ -Services for Google Shopping Type API -====================================== -.. toctree:: - :maxdepth: 2 diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/types_.rst b/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/types_.rst deleted file mode 100644 index ee93d33ec032..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/docs/type/types_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Types for Google Shopping Type API -=================================== - -.. automodule:: google.shopping.type.types - :members: - :show-inheritance: diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/__init__.py deleted file mode 100644 index 81e1b2cc88a3..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/__init__.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.shopping.type import gapic_version as package_version - -__version__ = package_version.__version__ - - - -from .types.types import Channel -from .types.types import CustomAttribute -from .types.types import Destination -from .types.types import Price -from .types.types import ReportingContext -from .types.types import Weight - -__all__ = ( -'Channel', -'CustomAttribute', -'Destination', -'Price', -'ReportingContext', -'Weight', -) diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_metadata.json b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_metadata.json deleted file mode 100644 index 284d1a73cfda..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_metadata.json +++ /dev/null @@ -1,7 +0,0 @@ - { - "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", - "language": "python", - "libraryPackage": "google.shopping.type", - "protoPackage": "google.shopping.type", - "schema": "1.0" -} diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_version.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_version.py deleted file mode 100644 index 558c8aab67c5..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/gapic_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-type/google-shopping-type-py/google/shopping/type/py.typed b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/py.typed deleted file mode 100644 index 5c0a2eb8cab8..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-shopping-type package uses inline types. diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/services/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/services/__init__.py deleted file mode 100644 index 8f6cf068242c..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/services/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-type/google-shopping-type-py/google/shopping/type/types/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/__init__.py deleted file mode 100644 index 4c5ee0230744..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .types import ( - Channel, - CustomAttribute, - Destination, - Price, - ReportingContext, - Weight, -) - -__all__ = ( - 'Channel', - 'CustomAttribute', - 'Destination', - 'Price', - 'ReportingContext', - 'Weight', -) diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/types.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/types.py deleted file mode 100644 index e860ce590cf6..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/google/shopping/type/types/types.py +++ /dev/null @@ -1,297 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.shopping.type', - manifest={ - 'Weight', - 'Price', - 'CustomAttribute', - 'Destination', - 'ReportingContext', - 'Channel', - }, -) - - -class Weight(proto.Message): - r"""The weight represented as the value in string and the unit. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - amount_micros (int): - Required. The weight represented as a number - in micros (1 million micros is an equivalent to - one's currency standard unit, for example, 1 kg - = 1000000 micros). - This field can also be set as infinity by - setting to -1. This field only support -1 and - positive value. - - This field is a member of `oneof`_ ``_amount_micros``. - unit (google.shopping.type.types.Weight.WeightUnit): - Required. The weight unit. - Acceptable values are: kg and lb - """ - class WeightUnit(proto.Enum): - r"""The weight unit. - - Values: - WEIGHT_UNIT_UNSPECIFIED (0): - unit unspecified - POUND (1): - lb unit. - KILOGRAM (2): - kg unit. - """ - WEIGHT_UNIT_UNSPECIFIED = 0 - POUND = 1 - KILOGRAM = 2 - - amount_micros: int = proto.Field( - proto.INT64, - number=1, - optional=True, - ) - unit: WeightUnit = proto.Field( - proto.ENUM, - number=2, - enum=WeightUnit, - ) - - -class Price(proto.Message): - r"""The price represented as a number and currency. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - amount_micros (int): - The price represented as a number in micros - (1 million micros is an equivalent to one's - currency standard unit, for example, 1 USD = - 1000000 micros). - - This field is a member of `oneof`_ ``_amount_micros``. - currency_code (str): - The currency of the price using three-letter acronyms - according to `ISO - 4217 `__. - - This field is a member of `oneof`_ ``_currency_code``. - """ - - amount_micros: int = proto.Field( - proto.INT64, - number=1, - optional=True, - ) - currency_code: str = proto.Field( - proto.STRING, - number=2, - optional=True, - ) - - -class CustomAttribute(proto.Message): - r"""A message that represents custom attributes. Exactly one of - ``value`` or ``group_values`` must not be empty. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - name (str): - The name of the attribute. - - This field is a member of `oneof`_ ``_name``. - value (str): - The value of the attribute. If ``value`` is not empty, - ``group_values`` must be empty. - - This field is a member of `oneof`_ ``_value``. - group_values (MutableSequence[google.shopping.type.types.CustomAttribute]): - Subattributes within this attribute group. If - ``group_values`` is not empty, ``value`` must be empty. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - optional=True, - ) - value: str = proto.Field( - proto.STRING, - number=2, - optional=True, - ) - group_values: MutableSequence['CustomAttribute'] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message='CustomAttribute', - ) - - -class Destination(proto.Message): - r"""Destinations available for a product. - - Destinations are used in Merchant Center to allow you to control - where the products from your data feed should be displayed. - - """ - class DestinationEnum(proto.Enum): - r"""Destination values. - - Values: - DESTINATION_ENUM_UNSPECIFIED (0): - Not specified. - SHOPPING_ADS (1): - `Shopping - ads `__. - DISPLAY_ADS (2): - `Display - ads `__. - LOCAL_INVENTORY_ADS (3): - `Local inventory - ads `__. - FREE_LISTINGS (4): - `Free - listings `__. - FREE_LOCAL_LISTINGS (5): - `Free local product - listings `__. - YOUTUBE_SHOPPING (6): - `YouTube - Shopping `__. - """ - DESTINATION_ENUM_UNSPECIFIED = 0 - SHOPPING_ADS = 1 - DISPLAY_ADS = 2 - LOCAL_INVENTORY_ADS = 3 - FREE_LISTINGS = 4 - FREE_LOCAL_LISTINGS = 5 - YOUTUBE_SHOPPING = 6 - - -class ReportingContext(proto.Message): - r"""Reporting contexts that your account and product issues apply to. - - Reporting contexts are groups of surfaces and formats for product - results on Google. They can represent the entire destination (for - example, `Shopping - ads `__) or a - subset of formats within a destination (for example, `Demand Gen - ads `__). - - """ - class ReportingContextEnum(proto.Enum): - r"""Reporting context values. - - Values: - REPORTING_CONTEXT_ENUM_UNSPECIFIED (0): - Not specified. - SHOPPING_ADS (1): - `Shopping - ads `__. - DISCOVERY_ADS (2): - Deprecated: Use ``DEMAND_GEN_ADS`` instead. `Discovery and - Demand Gen - ads `__. - DEMAND_GEN_ADS (13): - `Demand Gen - ads `__. - DEMAND_GEN_ADS_DISCOVER_SURFACE (14): - `Demand Gen ads on Discover - surface `__. - VIDEO_ADS (3): - `Video - ads `__. - DISPLAY_ADS (4): - `Display - ads `__. - LOCAL_INVENTORY_ADS (5): - `Local inventory - ads `__. - VEHICLE_INVENTORY_ADS (6): - `Vehicle inventory - ads `__. - FREE_LISTINGS (7): - `Free product - listings `__. - FREE_LOCAL_LISTINGS (8): - `Free local product - listings `__. - FREE_LOCAL_VEHICLE_LISTINGS (9): - `Free local vehicle - listings `__. - YOUTUBE_SHOPPING (10): - `YouTube - Shopping `__. - CLOUD_RETAIL (11): - `Cloud - retail `__. - LOCAL_CLOUD_RETAIL (12): - `Local cloud - retail `__. - """ - REPORTING_CONTEXT_ENUM_UNSPECIFIED = 0 - SHOPPING_ADS = 1 - DISCOVERY_ADS = 2 - DEMAND_GEN_ADS = 13 - DEMAND_GEN_ADS_DISCOVER_SURFACE = 14 - VIDEO_ADS = 3 - DISPLAY_ADS = 4 - LOCAL_INVENTORY_ADS = 5 - VEHICLE_INVENTORY_ADS = 6 - FREE_LISTINGS = 7 - FREE_LOCAL_LISTINGS = 8 - FREE_LOCAL_VEHICLE_LISTINGS = 9 - YOUTUBE_SHOPPING = 10 - CLOUD_RETAIL = 11 - LOCAL_CLOUD_RETAIL = 12 - - -class Channel(proto.Message): - r"""`Channel `__ of - a product. - - Channel is used to distinguish between online and local products. - - """ - class ChannelEnum(proto.Enum): - r"""Channel values. - - Values: - CHANNEL_ENUM_UNSPECIFIED (0): - Not specified. - ONLINE (1): - Online product. - LOCAL (2): - Local product. - """ - CHANNEL_ENUM_UNSPECIFIED = 0 - ONLINE = 1 - LOCAL = 2 - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/mypy.ini b/owl-bot-staging/google-shopping-type/google-shopping-type-py/mypy.ini deleted file mode 100644 index 574c5aed394b..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/mypy.ini +++ /dev/null @@ -1,3 +0,0 @@ -[mypy] -python_version = 3.7 -namespace_packages = True diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/noxfile.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/noxfile.py deleted file mode 100644 index 1011be60232e..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/noxfile.py +++ /dev/null @@ -1,280 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 re -import shutil -import subprocess -import sys - - -import nox # type: ignore - -ALL_PYTHON = [ - "3.7", - "3.8", - "3.9", - "3.10", - "3.11", - "3.12", - "3.13", -] - -CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() - -LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" -PACKAGE_NAME = 'google-shopping-type' - -BLACK_VERSION = "black==22.3.0" -BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] -DEFAULT_PYTHON_VERSION = "3.13" - -nox.sessions = [ - "unit", - "cover", - "mypy", - "check_lower_bounds" - # exclude update_lower_bounds from default - "docs", - "blacken", - "lint", - "prerelease_deps", -] - -@nox.session(python=ALL_PYTHON) -@nox.parametrize( - "protobuf_implementation", - [ "python", "upb", "cpp" ], -) -def unit(session, protobuf_implementation): - """Run the unit test suite.""" - - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): - session.skip("cpp implementation is not supported in python 3.11+") - - session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') - session.install('-e', '.', "-c", f"testing/constraints-{session.python}.txt") - - # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. - # The 'cpp' implementation requires Protobuf<4. - if protobuf_implementation == "cpp": - session.install("protobuf<4") - - session.run( - 'py.test', - '--quiet', - '--cov=google/shopping/type/', - '--cov=tests/', - '--cov-config=.coveragerc', - '--cov-report=term', - '--cov-report=html', - os.path.join('tests', 'unit', ''.join(session.posargs)), - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - -@nox.session(python=ALL_PYTHON[-1]) -@nox.parametrize( - "protobuf_implementation", - [ "python", "upb", "cpp" ], -) -def prerelease_deps(session, protobuf_implementation): - """Run the unit test suite against pre-release versions of dependencies.""" - - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): - session.skip("cpp implementation is not supported in python 3.11+") - - # Install test environment dependencies - session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') - - # Install the package without dependencies - session.install('-e', '.', '--no-deps') - - # We test the minimum dependency versions using the minimum Python - # version so the lowest python runtime that we test has a corresponding constraints - # file, located at `testing/constraints--.txt`, which contains all of the - # dependencies and extras. - with open( - CURRENT_DIRECTORY - / "testing" - / f"constraints-{ALL_PYTHON[0]}.txt", - encoding="utf-8", - ) as constraints_file: - constraints_text = constraints_file.read() - - # Ignore leading whitespace and comment lines. - constraints_deps = [ - match.group(1) - for match in re.finditer( - r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE - ) - ] - - session.install(*constraints_deps) - - prerel_deps = [ - "googleapis-common-protos", - "google-api-core", - "google-auth", - # Exclude grpcio!=1.67.0rc1 which does not support python 3.13 - "grpcio!=1.67.0rc1", - "grpcio-status", - "protobuf", - "proto-plus", - ] - - for dep in prerel_deps: - session.install("--pre", "--no-deps", "--upgrade", dep) - - # Remaining dependencies - other_deps = [ - "requests", - ] - session.install(*other_deps) - - # Print out prerelease package versions - - session.run("python", "-c", "import google.api_core; print(google.api_core.__version__)") - session.run("python", "-c", "import google.auth; print(google.auth.__version__)") - session.run("python", "-c", "import grpc; print(grpc.__version__)") - session.run( - "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" - ) - session.run( - "python", "-c", "import proto; print(proto.__version__)" - ) - - session.run( - 'py.test', - '--quiet', - '--cov=google/shopping/type/', - '--cov=tests/', - '--cov-config=.coveragerc', - '--cov-report=term', - '--cov-report=html', - os.path.join('tests', 'unit', ''.join(session.posargs)), - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - - -@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', - '-p', - '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, - ) diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/scripts/fixup_type_keywords.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/scripts/fixup_type_keywords.py deleted file mode 100644 index bae51b8ecbd3..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/scripts/fixup_type_keywords.py +++ /dev/null @@ -1,175 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 typeCallTransformer(cst.CSTTransformer): - CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') - METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { - } - - 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=typeCallTransformer(), -): - """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 type 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/google-shopping-type/google-shopping-type-py/setup.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/setup.py deleted file mode 100644 index 99bf51929d58..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/setup.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 re - -import setuptools # type: ignore - -package_root = os.path.abspath(os.path.dirname(__file__)) - -name = 'google-shopping-type' - - -description = "Google Shopping Type API client library" - -version = None - -with open(os.path.join(package_root, 'google/shopping/type/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) - assert (len(version_candidates) == 1) - version = version_candidates[0] - -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.1, <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.*", - # Exclude incompatible versions of `google-auth` - # See https://github.com/googleapis/google-cloud-python/issues/12364 - "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", - "proto-plus >= 1.22.3, <2.0.0dev", - "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", - "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", -] -extras = { -} -url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-shopping-type" - -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.find_namespace_packages() - if package.startswith("google") -] - -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", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Operating System :: OS Independent", - "Topic :: Internet", - ], - platforms="Posix; MacOS X; Windows", - packages=packages, - python_requires=">=3.7", - install_requires=dependencies, - extras_require=extras, - include_package_data=True, - zip_safe=False, -) diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.10.txt b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.10.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.10.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/google-shopping-type/google-shopping-type-py/testing/constraints-3.11.txt b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.11.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.11.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/google-shopping-type/google-shopping-type-py/testing/constraints-3.12.txt b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.12.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.12.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/google-shopping-type/google-shopping-type-py/testing/constraints-3.7.txt b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.7.txt deleted file mode 100644 index fc812592b0ee..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.7.txt +++ /dev/null @@ -1,10 +0,0 @@ -# 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.1 -google-auth==2.14.1 -proto-plus==1.22.3 -protobuf==3.20.2 diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.8.txt b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.8.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.8.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/google-shopping-type/google-shopping-type-py/testing/constraints-3.9.txt b/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.9.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.9.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/google-shopping-type/google-shopping-type-py/tests/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-type/google-shopping-type-py/tests/unit/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-type/google-shopping-type-py/tests/unit/gapic/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/gapic/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/gapic/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google-shopping-type/google-shopping-type-py/tests/unit/gapic/type/__init__.py b/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/gapic/type/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/google-shopping-type/google-shopping-type-py/tests/unit/gapic/type/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/grafeas/v1/.coveragerc b/owl-bot-staging/grafeas/v1/.coveragerc deleted file mode 100644 index 4e55acc51c44..000000000000 --- a/owl-bot-staging/grafeas/v1/.coveragerc +++ /dev/null @@ -1,13 +0,0 @@ -[run] -branch = True - -[report] -show_missing = True -omit = - grafeas/grafeas/__init__.py - grafeas/grafeas/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/grafeas/v1/.flake8 b/owl-bot-staging/grafeas/v1/.flake8 deleted file mode 100644 index 29227d4cf419..000000000000 --- a/owl-bot-staging/grafeas/v1/.flake8 +++ /dev/null @@ -1,33 +0,0 @@ -# -*- 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/grafeas/v1/MANIFEST.in b/owl-bot-staging/grafeas/v1/MANIFEST.in deleted file mode 100644 index 075904e53516..000000000000 --- a/owl-bot-staging/grafeas/v1/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -recursive-include grafeas/grafeas *.py -recursive-include grafeas/grafeas_v1 *.py diff --git a/owl-bot-staging/grafeas/v1/README.rst b/owl-bot-staging/grafeas/v1/README.rst deleted file mode 100644 index 0f879492ca1d..000000000000 --- a/owl-bot-staging/grafeas/v1/README.rst +++ /dev/null @@ -1,49 +0,0 @@ -Python Client for Grafeas Grafeas 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 Grafeas Grafeas 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/grafeas/v1/docs/_static/custom.css b/owl-bot-staging/grafeas/v1/docs/_static/custom.css deleted file mode 100644 index 06423be0b592..000000000000 --- a/owl-bot-staging/grafeas/v1/docs/_static/custom.css +++ /dev/null @@ -1,3 +0,0 @@ -dl.field-list > dt { - min-width: 100px -} diff --git a/owl-bot-staging/grafeas/v1/docs/conf.py b/owl-bot-staging/grafeas/v1/docs/conf.py deleted file mode 100644 index e43817cf2e74..000000000000 --- a/owl-bot-staging/grafeas/v1/docs/conf.py +++ /dev/null @@ -1,376 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -# grafeas 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"grafeas" -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": "Grafeas 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 = "grafeas-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, - "grafeas.tex", - u"grafeas 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, - "grafeas", - u"Grafeas Grafeas 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, - "grafeas", - u"grafeas Documentation", - author, - "grafeas", - "GAPIC library for Grafeas Grafeas 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/grafeas/v1/docs/grafeas_v1/grafeas.rst b/owl-bot-staging/grafeas/v1/docs/grafeas_v1/grafeas.rst deleted file mode 100644 index 7339fabecaee..000000000000 --- a/owl-bot-staging/grafeas/v1/docs/grafeas_v1/grafeas.rst +++ /dev/null @@ -1,10 +0,0 @@ -Grafeas -------------------------- - -.. automodule:: grafeas.grafeas_v1.services.grafeas - :members: - :inherited-members: - -.. automodule:: grafeas.grafeas_v1.services.grafeas.pagers - :members: - :inherited-members: diff --git a/owl-bot-staging/grafeas/v1/docs/grafeas_v1/services_.rst b/owl-bot-staging/grafeas/v1/docs/grafeas_v1/services_.rst deleted file mode 100644 index ca38222018ff..000000000000 --- a/owl-bot-staging/grafeas/v1/docs/grafeas_v1/services_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Services for Grafeas Grafeas v1 API -=================================== -.. toctree:: - :maxdepth: 2 - - grafeas diff --git a/owl-bot-staging/grafeas/v1/docs/grafeas_v1/types_.rst b/owl-bot-staging/grafeas/v1/docs/grafeas_v1/types_.rst deleted file mode 100644 index 5808795e6eb1..000000000000 --- a/owl-bot-staging/grafeas/v1/docs/grafeas_v1/types_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Types for Grafeas Grafeas v1 API -================================ - -.. automodule:: grafeas.grafeas_v1.types - :members: - :show-inheritance: diff --git a/owl-bot-staging/grafeas/v1/docs/index.rst b/owl-bot-staging/grafeas/v1/docs/index.rst deleted file mode 100644 index 35750509477c..000000000000 --- a/owl-bot-staging/grafeas/v1/docs/index.rst +++ /dev/null @@ -1,7 +0,0 @@ -API Reference -------------- -.. toctree:: - :maxdepth: 2 - - grafeas_v1/services_ - grafeas_v1/types_ diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas/__init__.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas/__init__.py deleted file mode 100644 index f2282fa0cc79..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas/__init__.py +++ /dev/null @@ -1,211 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from grafeas.grafeas import gapic_version as package_version - -__version__ = package_version.__version__ - - -from grafeas.grafeas_v1.services.grafeas.client import GrafeasClient -from grafeas.grafeas_v1.services.grafeas.async_client import GrafeasAsyncClient - -from grafeas.grafeas_v1.types.attestation import AttestationNote -from grafeas.grafeas_v1.types.attestation import AttestationOccurrence -from grafeas.grafeas_v1.types.attestation import Jwt -from grafeas.grafeas_v1.types.build import BuildNote -from grafeas.grafeas_v1.types.build import BuildOccurrence -from grafeas.grafeas_v1.types.common import Digest -from grafeas.grafeas_v1.types.common import Envelope -from grafeas.grafeas_v1.types.common import EnvelopeSignature -from grafeas.grafeas_v1.types.common import FileLocation -from grafeas.grafeas_v1.types.common import License -from grafeas.grafeas_v1.types.common import RelatedUrl -from grafeas.grafeas_v1.types.common import Signature -from grafeas.grafeas_v1.types.common import NoteKind -from grafeas.grafeas_v1.types.compliance import ComplianceNote -from grafeas.grafeas_v1.types.compliance import ComplianceOccurrence -from grafeas.grafeas_v1.types.compliance import ComplianceVersion -from grafeas.grafeas_v1.types.compliance import NonCompliantFile -from grafeas.grafeas_v1.types.cvss import CVSS -from grafeas.grafeas_v1.types.cvss import CVSSv3 -from grafeas.grafeas_v1.types.cvss import CVSSVersion -from grafeas.grafeas_v1.types.deployment import DeploymentNote -from grafeas.grafeas_v1.types.deployment import DeploymentOccurrence -from grafeas.grafeas_v1.types.discovery import DiscoveryNote -from grafeas.grafeas_v1.types.discovery import DiscoveryOccurrence -from grafeas.grafeas_v1.types.dsse_attestation import DSSEAttestationNote -from grafeas.grafeas_v1.types.dsse_attestation import DSSEAttestationOccurrence -from grafeas.grafeas_v1.types.grafeas import BatchCreateNotesRequest -from grafeas.grafeas_v1.types.grafeas import BatchCreateNotesResponse -from grafeas.grafeas_v1.types.grafeas import BatchCreateOccurrencesRequest -from grafeas.grafeas_v1.types.grafeas import BatchCreateOccurrencesResponse -from grafeas.grafeas_v1.types.grafeas import CreateNoteRequest -from grafeas.grafeas_v1.types.grafeas import CreateOccurrenceRequest -from grafeas.grafeas_v1.types.grafeas import DeleteNoteRequest -from grafeas.grafeas_v1.types.grafeas import DeleteOccurrenceRequest -from grafeas.grafeas_v1.types.grafeas import GetNoteRequest -from grafeas.grafeas_v1.types.grafeas import GetOccurrenceNoteRequest -from grafeas.grafeas_v1.types.grafeas import GetOccurrenceRequest -from grafeas.grafeas_v1.types.grafeas import ListNoteOccurrencesRequest -from grafeas.grafeas_v1.types.grafeas import ListNoteOccurrencesResponse -from grafeas.grafeas_v1.types.grafeas import ListNotesRequest -from grafeas.grafeas_v1.types.grafeas import ListNotesResponse -from grafeas.grafeas_v1.types.grafeas import ListOccurrencesRequest -from grafeas.grafeas_v1.types.grafeas import ListOccurrencesResponse -from grafeas.grafeas_v1.types.grafeas import Note -from grafeas.grafeas_v1.types.grafeas import Occurrence -from grafeas.grafeas_v1.types.grafeas import UpdateNoteRequest -from grafeas.grafeas_v1.types.grafeas import UpdateOccurrenceRequest -from grafeas.grafeas_v1.types.image import Fingerprint -from grafeas.grafeas_v1.types.image import ImageNote -from grafeas.grafeas_v1.types.image import ImageOccurrence -from grafeas.grafeas_v1.types.image import Layer -from grafeas.grafeas_v1.types.intoto_provenance import BuilderConfig -from grafeas.grafeas_v1.types.intoto_provenance import Completeness -from grafeas.grafeas_v1.types.intoto_provenance import InTotoProvenance -from grafeas.grafeas_v1.types.intoto_provenance import Metadata -from grafeas.grafeas_v1.types.intoto_provenance import Recipe -from grafeas.grafeas_v1.types.intoto_statement import InTotoSlsaProvenanceV1 -from grafeas.grafeas_v1.types.intoto_statement import InTotoStatement -from grafeas.grafeas_v1.types.intoto_statement import Subject -from grafeas.grafeas_v1.types.package import Distribution -from grafeas.grafeas_v1.types.package import Location -from grafeas.grafeas_v1.types.package import PackageNote -from grafeas.grafeas_v1.types.package import PackageOccurrence -from grafeas.grafeas_v1.types.package import Version -from grafeas.grafeas_v1.types.package import Architecture -from grafeas.grafeas_v1.types.provenance import AliasContext -from grafeas.grafeas_v1.types.provenance import Artifact -from grafeas.grafeas_v1.types.provenance import BuildProvenance -from grafeas.grafeas_v1.types.provenance import CloudRepoSourceContext -from grafeas.grafeas_v1.types.provenance import Command -from grafeas.grafeas_v1.types.provenance import FileHashes -from grafeas.grafeas_v1.types.provenance import GerritSourceContext -from grafeas.grafeas_v1.types.provenance import GitSourceContext -from grafeas.grafeas_v1.types.provenance import Hash -from grafeas.grafeas_v1.types.provenance import ProjectRepoId -from grafeas.grafeas_v1.types.provenance import RepoId -from grafeas.grafeas_v1.types.provenance import Source -from grafeas.grafeas_v1.types.provenance import SourceContext -from grafeas.grafeas_v1.types.sbom import SbomReferenceIntotoPayload -from grafeas.grafeas_v1.types.sbom import SbomReferenceIntotoPredicate -from grafeas.grafeas_v1.types.sbom import SBOMReferenceNote -from grafeas.grafeas_v1.types.sbom import SBOMReferenceOccurrence -from grafeas.grafeas_v1.types.severity import Severity -from grafeas.grafeas_v1.types.slsa_provenance import SlsaProvenance -from grafeas.grafeas_v1.types.slsa_provenance_zero_two import SlsaProvenanceZeroTwo -from grafeas.grafeas_v1.types.upgrade import UpgradeDistribution -from grafeas.grafeas_v1.types.upgrade import UpgradeNote -from grafeas.grafeas_v1.types.upgrade import UpgradeOccurrence -from grafeas.grafeas_v1.types.upgrade import WindowsUpdate -from grafeas.grafeas_v1.types.vex import VulnerabilityAssessmentNote -from grafeas.grafeas_v1.types.vulnerability import VulnerabilityNote -from grafeas.grafeas_v1.types.vulnerability import VulnerabilityOccurrence - -__all__ = ('GrafeasClient', - 'GrafeasAsyncClient', - 'AttestationNote', - 'AttestationOccurrence', - 'Jwt', - 'BuildNote', - 'BuildOccurrence', - 'Digest', - 'Envelope', - 'EnvelopeSignature', - 'FileLocation', - 'License', - 'RelatedUrl', - 'Signature', - 'NoteKind', - 'ComplianceNote', - 'ComplianceOccurrence', - 'ComplianceVersion', - 'NonCompliantFile', - 'CVSS', - 'CVSSv3', - 'CVSSVersion', - 'DeploymentNote', - 'DeploymentOccurrence', - 'DiscoveryNote', - 'DiscoveryOccurrence', - 'DSSEAttestationNote', - 'DSSEAttestationOccurrence', - 'BatchCreateNotesRequest', - 'BatchCreateNotesResponse', - 'BatchCreateOccurrencesRequest', - 'BatchCreateOccurrencesResponse', - 'CreateNoteRequest', - 'CreateOccurrenceRequest', - 'DeleteNoteRequest', - 'DeleteOccurrenceRequest', - 'GetNoteRequest', - 'GetOccurrenceNoteRequest', - 'GetOccurrenceRequest', - 'ListNoteOccurrencesRequest', - 'ListNoteOccurrencesResponse', - 'ListNotesRequest', - 'ListNotesResponse', - 'ListOccurrencesRequest', - 'ListOccurrencesResponse', - 'Note', - 'Occurrence', - 'UpdateNoteRequest', - 'UpdateOccurrenceRequest', - 'Fingerprint', - 'ImageNote', - 'ImageOccurrence', - 'Layer', - 'BuilderConfig', - 'Completeness', - 'InTotoProvenance', - 'Metadata', - 'Recipe', - 'InTotoSlsaProvenanceV1', - 'InTotoStatement', - 'Subject', - 'Distribution', - 'Location', - 'PackageNote', - 'PackageOccurrence', - 'Version', - 'Architecture', - 'AliasContext', - 'Artifact', - 'BuildProvenance', - 'CloudRepoSourceContext', - 'Command', - 'FileHashes', - 'GerritSourceContext', - 'GitSourceContext', - 'Hash', - 'ProjectRepoId', - 'RepoId', - 'Source', - 'SourceContext', - 'SbomReferenceIntotoPayload', - 'SbomReferenceIntotoPredicate', - 'SBOMReferenceNote', - 'SBOMReferenceOccurrence', - 'Severity', - 'SlsaProvenance', - 'SlsaProvenanceZeroTwo', - 'UpgradeDistribution', - 'UpgradeNote', - 'UpgradeOccurrence', - 'WindowsUpdate', - 'VulnerabilityAssessmentNote', - 'VulnerabilityNote', - 'VulnerabilityOccurrence', -) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas/gapic_version.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas/gapic_version.py deleted file mode 100644 index 558c8aab67c5..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas/gapic_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/grafeas/v1/grafeas/grafeas/py.typed b/owl-bot-staging/grafeas/v1/grafeas/grafeas/py.typed deleted file mode 100644 index 49e8f71d60b7..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The grafeas package uses inline types. diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/__init__.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/__init__.py deleted file mode 100644 index 7a4f4fa690fd..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/__init__.py +++ /dev/null @@ -1,212 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from grafeas.grafeas_v1 import gapic_version as package_version - -__version__ = package_version.__version__ - - -from .services.grafeas import GrafeasClient -from .services.grafeas import GrafeasAsyncClient - -from .types.attestation import AttestationNote -from .types.attestation import AttestationOccurrence -from .types.attestation import Jwt -from .types.build import BuildNote -from .types.build import BuildOccurrence -from .types.common import Digest -from .types.common import Envelope -from .types.common import EnvelopeSignature -from .types.common import FileLocation -from .types.common import License -from .types.common import RelatedUrl -from .types.common import Signature -from .types.common import NoteKind -from .types.compliance import ComplianceNote -from .types.compliance import ComplianceOccurrence -from .types.compliance import ComplianceVersion -from .types.compliance import NonCompliantFile -from .types.cvss import CVSS -from .types.cvss import CVSSv3 -from .types.cvss import CVSSVersion -from .types.deployment import DeploymentNote -from .types.deployment import DeploymentOccurrence -from .types.discovery import DiscoveryNote -from .types.discovery import DiscoveryOccurrence -from .types.dsse_attestation import DSSEAttestationNote -from .types.dsse_attestation import DSSEAttestationOccurrence -from .types.grafeas import BatchCreateNotesRequest -from .types.grafeas import BatchCreateNotesResponse -from .types.grafeas import BatchCreateOccurrencesRequest -from .types.grafeas import BatchCreateOccurrencesResponse -from .types.grafeas import CreateNoteRequest -from .types.grafeas import CreateOccurrenceRequest -from .types.grafeas import DeleteNoteRequest -from .types.grafeas import DeleteOccurrenceRequest -from .types.grafeas import GetNoteRequest -from .types.grafeas import GetOccurrenceNoteRequest -from .types.grafeas import GetOccurrenceRequest -from .types.grafeas import ListNoteOccurrencesRequest -from .types.grafeas import ListNoteOccurrencesResponse -from .types.grafeas import ListNotesRequest -from .types.grafeas import ListNotesResponse -from .types.grafeas import ListOccurrencesRequest -from .types.grafeas import ListOccurrencesResponse -from .types.grafeas import Note -from .types.grafeas import Occurrence -from .types.grafeas import UpdateNoteRequest -from .types.grafeas import UpdateOccurrenceRequest -from .types.image import Fingerprint -from .types.image import ImageNote -from .types.image import ImageOccurrence -from .types.image import Layer -from .types.intoto_provenance import BuilderConfig -from .types.intoto_provenance import Completeness -from .types.intoto_provenance import InTotoProvenance -from .types.intoto_provenance import Metadata -from .types.intoto_provenance import Recipe -from .types.intoto_statement import InTotoSlsaProvenanceV1 -from .types.intoto_statement import InTotoStatement -from .types.intoto_statement import Subject -from .types.package import Distribution -from .types.package import Location -from .types.package import PackageNote -from .types.package import PackageOccurrence -from .types.package import Version -from .types.package import Architecture -from .types.provenance import AliasContext -from .types.provenance import Artifact -from .types.provenance import BuildProvenance -from .types.provenance import CloudRepoSourceContext -from .types.provenance import Command -from .types.provenance import FileHashes -from .types.provenance import GerritSourceContext -from .types.provenance import GitSourceContext -from .types.provenance import Hash -from .types.provenance import ProjectRepoId -from .types.provenance import RepoId -from .types.provenance import Source -from .types.provenance import SourceContext -from .types.sbom import SbomReferenceIntotoPayload -from .types.sbom import SbomReferenceIntotoPredicate -from .types.sbom import SBOMReferenceNote -from .types.sbom import SBOMReferenceOccurrence -from .types.severity import Severity -from .types.slsa_provenance import SlsaProvenance -from .types.slsa_provenance_zero_two import SlsaProvenanceZeroTwo -from .types.upgrade import UpgradeDistribution -from .types.upgrade import UpgradeNote -from .types.upgrade import UpgradeOccurrence -from .types.upgrade import WindowsUpdate -from .types.vex import VulnerabilityAssessmentNote -from .types.vulnerability import VulnerabilityNote -from .types.vulnerability import VulnerabilityOccurrence - -__all__ = ( - 'GrafeasAsyncClient', -'AliasContext', -'Architecture', -'Artifact', -'AttestationNote', -'AttestationOccurrence', -'BatchCreateNotesRequest', -'BatchCreateNotesResponse', -'BatchCreateOccurrencesRequest', -'BatchCreateOccurrencesResponse', -'BuildNote', -'BuildOccurrence', -'BuildProvenance', -'BuilderConfig', -'CVSS', -'CVSSVersion', -'CVSSv3', -'CloudRepoSourceContext', -'Command', -'Completeness', -'ComplianceNote', -'ComplianceOccurrence', -'ComplianceVersion', -'CreateNoteRequest', -'CreateOccurrenceRequest', -'DSSEAttestationNote', -'DSSEAttestationOccurrence', -'DeleteNoteRequest', -'DeleteOccurrenceRequest', -'DeploymentNote', -'DeploymentOccurrence', -'Digest', -'DiscoveryNote', -'DiscoveryOccurrence', -'Distribution', -'Envelope', -'EnvelopeSignature', -'FileHashes', -'FileLocation', -'Fingerprint', -'GerritSourceContext', -'GetNoteRequest', -'GetOccurrenceNoteRequest', -'GetOccurrenceRequest', -'GitSourceContext', -'GrafeasClient', -'Hash', -'ImageNote', -'ImageOccurrence', -'InTotoProvenance', -'InTotoSlsaProvenanceV1', -'InTotoStatement', -'Jwt', -'Layer', -'License', -'ListNoteOccurrencesRequest', -'ListNoteOccurrencesResponse', -'ListNotesRequest', -'ListNotesResponse', -'ListOccurrencesRequest', -'ListOccurrencesResponse', -'Location', -'Metadata', -'NonCompliantFile', -'Note', -'NoteKind', -'Occurrence', -'PackageNote', -'PackageOccurrence', -'ProjectRepoId', -'Recipe', -'RelatedUrl', -'RepoId', -'SBOMReferenceNote', -'SBOMReferenceOccurrence', -'SbomReferenceIntotoPayload', -'SbomReferenceIntotoPredicate', -'Severity', -'Signature', -'SlsaProvenance', -'SlsaProvenanceZeroTwo', -'Source', -'SourceContext', -'Subject', -'UpdateNoteRequest', -'UpdateOccurrenceRequest', -'UpgradeDistribution', -'UpgradeNote', -'UpgradeOccurrence', -'Version', -'VulnerabilityAssessmentNote', -'VulnerabilityNote', -'VulnerabilityOccurrence', -'WindowsUpdate', -) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_metadata.json b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_metadata.json deleted file mode 100644 index ec505dda48a9..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_metadata.json +++ /dev/null @@ -1,238 +0,0 @@ - { - "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", - "language": "python", - "libraryPackage": "grafeas.grafeas_v1", - "protoPackage": "grafeas.v1", - "schema": "1.0", - "services": { - "Grafeas": { - "clients": { - "grpc": { - "libraryClient": "GrafeasClient", - "rpcs": { - "BatchCreateNotes": { - "methods": [ - "batch_create_notes" - ] - }, - "BatchCreateOccurrences": { - "methods": [ - "batch_create_occurrences" - ] - }, - "CreateNote": { - "methods": [ - "create_note" - ] - }, - "CreateOccurrence": { - "methods": [ - "create_occurrence" - ] - }, - "DeleteNote": { - "methods": [ - "delete_note" - ] - }, - "DeleteOccurrence": { - "methods": [ - "delete_occurrence" - ] - }, - "GetNote": { - "methods": [ - "get_note" - ] - }, - "GetOccurrence": { - "methods": [ - "get_occurrence" - ] - }, - "GetOccurrenceNote": { - "methods": [ - "get_occurrence_note" - ] - }, - "ListNoteOccurrences": { - "methods": [ - "list_note_occurrences" - ] - }, - "ListNotes": { - "methods": [ - "list_notes" - ] - }, - "ListOccurrences": { - "methods": [ - "list_occurrences" - ] - }, - "UpdateNote": { - "methods": [ - "update_note" - ] - }, - "UpdateOccurrence": { - "methods": [ - "update_occurrence" - ] - } - } - }, - "grpc-async": { - "libraryClient": "GrafeasAsyncClient", - "rpcs": { - "BatchCreateNotes": { - "methods": [ - "batch_create_notes" - ] - }, - "BatchCreateOccurrences": { - "methods": [ - "batch_create_occurrences" - ] - }, - "CreateNote": { - "methods": [ - "create_note" - ] - }, - "CreateOccurrence": { - "methods": [ - "create_occurrence" - ] - }, - "DeleteNote": { - "methods": [ - "delete_note" - ] - }, - "DeleteOccurrence": { - "methods": [ - "delete_occurrence" - ] - }, - "GetNote": { - "methods": [ - "get_note" - ] - }, - "GetOccurrence": { - "methods": [ - "get_occurrence" - ] - }, - "GetOccurrenceNote": { - "methods": [ - "get_occurrence_note" - ] - }, - "ListNoteOccurrences": { - "methods": [ - "list_note_occurrences" - ] - }, - "ListNotes": { - "methods": [ - "list_notes" - ] - }, - "ListOccurrences": { - "methods": [ - "list_occurrences" - ] - }, - "UpdateNote": { - "methods": [ - "update_note" - ] - }, - "UpdateOccurrence": { - "methods": [ - "update_occurrence" - ] - } - } - }, - "rest": { - "libraryClient": "GrafeasClient", - "rpcs": { - "BatchCreateNotes": { - "methods": [ - "batch_create_notes" - ] - }, - "BatchCreateOccurrences": { - "methods": [ - "batch_create_occurrences" - ] - }, - "CreateNote": { - "methods": [ - "create_note" - ] - }, - "CreateOccurrence": { - "methods": [ - "create_occurrence" - ] - }, - "DeleteNote": { - "methods": [ - "delete_note" - ] - }, - "DeleteOccurrence": { - "methods": [ - "delete_occurrence" - ] - }, - "GetNote": { - "methods": [ - "get_note" - ] - }, - "GetOccurrence": { - "methods": [ - "get_occurrence" - ] - }, - "GetOccurrenceNote": { - "methods": [ - "get_occurrence_note" - ] - }, - "ListNoteOccurrences": { - "methods": [ - "list_note_occurrences" - ] - }, - "ListNotes": { - "methods": [ - "list_notes" - ] - }, - "ListOccurrences": { - "methods": [ - "list_occurrences" - ] - }, - "UpdateNote": { - "methods": [ - "update_note" - ] - }, - "UpdateOccurrence": { - "methods": [ - "update_occurrence" - ] - } - } - } - } - } - } -} diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_version.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_version.py deleted file mode 100644 index 558c8aab67c5..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/gapic_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/grafeas/v1/grafeas/grafeas_v1/py.typed b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/py.typed deleted file mode 100644 index 49e8f71d60b7..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The grafeas package uses inline types. diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/__init__.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/__init__.py deleted file mode 100644 index 8f6cf068242c..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/grafeas/v1/grafeas/grafeas_v1/services/grafeas/__init__.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/__init__.py deleted file mode 100644 index b1d682230d78..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 GrafeasClient -from .async_client import GrafeasAsyncClient - -__all__ = ( - 'GrafeasClient', - 'GrafeasAsyncClient', -) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/async_client.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/async_client.py deleted file mode 100644 index 54992211d44a..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/async_client.py +++ /dev/null @@ -1,1836 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 re -from typing import Dict, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union - -from grafeas.grafeas_v1 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - - -try: - OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -from grafeas.grafeas_v1.services.grafeas import pagers -from grafeas.grafeas_v1.types import attestation -from grafeas.grafeas_v1.types import build -from grafeas.grafeas_v1.types import common -from grafeas.grafeas_v1.types import compliance -from grafeas.grafeas_v1.types import deployment -from grafeas.grafeas_v1.types import discovery -from grafeas.grafeas_v1.types import dsse_attestation -from grafeas.grafeas_v1.types import grafeas -from grafeas.grafeas_v1.types import image -from grafeas.grafeas_v1.types import package -from grafeas.grafeas_v1.types import sbom -from grafeas.grafeas_v1.types import upgrade -from grafeas.grafeas_v1.types import vex -from grafeas.grafeas_v1.types import vulnerability -from .transports.base import GrafeasTransport, DEFAULT_CLIENT_INFO -from .transports.grpc_asyncio import GrafeasGrpcAsyncIOTransport -from .client import GrafeasClient - - -class GrafeasAsyncClient: - """`Grafeas `__ API. - - Retrieves analysis results of Cloud components such as Docker - container images. - - Analysis results are stored as a series of occurrences. An - ``Occurrence`` contains information about a specific analysis - instance on a resource. An occurrence refers to a ``Note``. A note - contains details describing the analysis and is generally stored in - a separate project, called a ``Provider``. Multiple occurrences can - refer to the same note. - - For example, an SSL vulnerability could affect multiple images. In - this case, there would be one note for the vulnerability and an - occurrence for each image with the vulnerability referring to that - note. - """ - - _client: GrafeasClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = GrafeasClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = GrafeasClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = GrafeasClient._DEFAULT_ENDPOINT_TEMPLATE - _DEFAULT_UNIVERSE = GrafeasClient._DEFAULT_UNIVERSE - - note_path = staticmethod(GrafeasClient.note_path) - parse_note_path = staticmethod(GrafeasClient.parse_note_path) - occurrence_path = staticmethod(GrafeasClient.occurrence_path) - parse_occurrence_path = staticmethod(GrafeasClient.parse_occurrence_path) - project_path = staticmethod(GrafeasClient.project_path) - parse_project_path = staticmethod(GrafeasClient.parse_project_path) - common_billing_account_path = staticmethod(GrafeasClient.common_billing_account_path) - parse_common_billing_account_path = staticmethod(GrafeasClient.parse_common_billing_account_path) - common_folder_path = staticmethod(GrafeasClient.common_folder_path) - parse_common_folder_path = staticmethod(GrafeasClient.parse_common_folder_path) - common_organization_path = staticmethod(GrafeasClient.common_organization_path) - parse_common_organization_path = staticmethod(GrafeasClient.parse_common_organization_path) - common_project_path = staticmethod(GrafeasClient.common_project_path) - parse_common_project_path = staticmethod(GrafeasClient.parse_common_project_path) - common_location_path = staticmethod(GrafeasClient.common_location_path) - parse_common_location_path = staticmethod(GrafeasClient.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: - GrafeasAsyncClient: The constructed client. - """ - return GrafeasClient.from_service_account_info.__func__(GrafeasAsyncClient, 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: - GrafeasAsyncClient: The constructed client. - """ - return GrafeasClient.from_service_account_file.__func__(GrafeasAsyncClient, 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 GrafeasClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> GrafeasTransport: - """Returns the transport used by the client instance. - - Returns: - GrafeasTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = GrafeasClient.get_transport_class - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[Union[str, GrafeasTransport, Callable[..., GrafeasTransport]]] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the grafeas async 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 (Optional[Union[str,GrafeasTransport,Callable[..., GrafeasTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the GrafeasTransport constructor. - 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. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "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). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS 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. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - 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. - """ - self._client = GrafeasClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - - ) - - async def get_occurrence(self, - request: Optional[Union[grafeas.GetOccurrenceRequest, 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]] = (), - ) -> grafeas.Occurrence: - r"""Gets the specified occurrence. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - async def sample_get_occurrence(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.GetOccurrenceRequest( - name="name_value", - ) - - # Make the request - response = await client.get_occurrence(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.GetOccurrenceRequest, dict]]): - The request object. Request to get an occurrence. - name (:class:`str`): - The name of the occurrence in the form of - ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_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_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.types.Occurrence: - An instance of an analysis type that - has been found on a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.GetOccurrenceRequest): - request = grafeas.GetOccurrenceRequest(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._client._transport._wrapped_methods[self._client._transport.get_occurrence] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def list_occurrences(self, - request: Optional[Union[grafeas.ListOccurrencesRequest, dict]] = None, - *, - parent: Optional[str] = None, - filter: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> pagers.ListOccurrencesAsyncPager: - r"""Lists occurrences for the specified 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 grafeas import grafeas_v1 - - async def sample_list_occurrences(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.ListOccurrencesRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_occurrences(request=request) - - # Handle the response - async for response in page_result: - print(response) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.ListOccurrencesRequest, dict]]): - The request object. Request to list occurrences. - parent (:class:`str`): - The name of the project to list occurrences for in the - form of ``projects/[PROJECT_ID]``. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - filter (:class:`str`): - The filter expression. - This corresponds to the ``filter`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesAsyncPager: - Response for listing occurrences. - - 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, filter]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.ListOccurrencesRequest): - request = grafeas.ListOccurrencesRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if filter is not None: - request.filter = filter - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[self._client._transport.list_occurrences] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # 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.ListOccurrencesAsyncPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def delete_occurrence(self, - request: Optional[Union[grafeas.DeleteOccurrenceRequest, 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 the specified occurrence. For example, use - this method to delete an occurrence when the occurrence - is no longer applicable for the given resource. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - async def sample_delete_occurrence(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.DeleteOccurrenceRequest( - name="name_value", - ) - - # Make the request - await client.delete_occurrence(request=request) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.DeleteOccurrenceRequest, dict]]): - The request object. Request to delete an occurrence. - name (:class:`str`): - The name of the occurrence in the form of - ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_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_async.AsyncRetry): Designation of what errors, if any, - should be 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.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.DeleteOccurrenceRequest): - request = grafeas.DeleteOccurrenceRequest(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._client._transport._wrapped_methods[self._client._transport.delete_occurrence] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - async def create_occurrence(self, - request: Optional[Union[grafeas.CreateOccurrenceRequest, dict]] = None, - *, - parent: Optional[str] = None, - occurrence: Optional[grafeas.Occurrence] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> grafeas.Occurrence: - r"""Creates a new occurrence. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - async def sample_create_occurrence(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.CreateOccurrenceRequest( - parent="parent_value", - ) - - # Make the request - response = await client.create_occurrence(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.CreateOccurrenceRequest, dict]]): - The request object. Request to create a new occurrence. - parent (:class:`str`): - The name of the project in the form of - ``projects/[PROJECT_ID]``, under which the occurrence is - to be created. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - occurrence (:class:`grafeas.grafeas_v1.types.Occurrence`): - The occurrence to create. - This corresponds to the ``occurrence`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.types.Occurrence: - An instance of an analysis type that - has been found on a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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, occurrence]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.CreateOccurrenceRequest): - request = grafeas.CreateOccurrenceRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if occurrence is not None: - request.occurrence = occurrence - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[self._client._transport.create_occurrence] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def batch_create_occurrences(self, - request: Optional[Union[grafeas.BatchCreateOccurrencesRequest, dict]] = None, - *, - parent: Optional[str] = None, - occurrences: Optional[MutableSequence[grafeas.Occurrence]] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> grafeas.BatchCreateOccurrencesResponse: - r"""Creates new occurrences in batch. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - async def sample_batch_create_occurrences(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.BatchCreateOccurrencesRequest( - parent="parent_value", - ) - - # Make the request - response = await client.batch_create_occurrences(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.BatchCreateOccurrencesRequest, dict]]): - The request object. Request to create occurrences in - batch. - parent (:class:`str`): - The name of the project in the form of - ``projects/[PROJECT_ID]``, under which the occurrences - are to be created. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - occurrences (:class:`MutableSequence[grafeas.grafeas_v1.types.Occurrence]`): - The occurrences to create. Max - allowed length is 1000. - - This corresponds to the ``occurrences`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse: - Response for creating occurrences in - batch. - - """ - # Create or coerce a protobuf request object. - # - Quick 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, occurrences]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.BatchCreateOccurrencesRequest): - request = grafeas.BatchCreateOccurrencesRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if occurrences: - request.occurrences.extend(occurrences) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[self._client._transport.batch_create_occurrences] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def update_occurrence(self, - request: Optional[Union[grafeas.UpdateOccurrenceRequest, dict]] = None, - *, - name: Optional[str] = None, - occurrence: Optional[grafeas.Occurrence] = 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]] = (), - ) -> grafeas.Occurrence: - r"""Updates the specified occurrence. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - async def sample_update_occurrence(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.UpdateOccurrenceRequest( - name="name_value", - ) - - # Make the request - response = await client.update_occurrence(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.UpdateOccurrenceRequest, dict]]): - The request object. Request to update an occurrence. - name (:class:`str`): - The name of the occurrence in the form of - ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - occurrence (:class:`grafeas.grafeas_v1.types.Occurrence`): - The updated occurrence. - This corresponds to the ``occurrence`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): - The fields to 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_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.types.Occurrence: - An instance of an analysis type that - has been found on a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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, occurrence, 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.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.UpdateOccurrenceRequest): - request = grafeas.UpdateOccurrenceRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - if occurrence is not None: - request.occurrence = occurrence - 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._client._transport._wrapped_methods[self._client._transport.update_occurrence] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def get_occurrence_note(self, - request: Optional[Union[grafeas.GetOccurrenceNoteRequest, 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]] = (), - ) -> grafeas.Note: - r"""Gets the note attached to the specified occurrence. - Consumer projects can use this method to get a note that - belongs to a provider 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 grafeas import grafeas_v1 - - async def sample_get_occurrence_note(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.GetOccurrenceNoteRequest( - name="name_value", - ) - - # Make the request - response = await client.get_occurrence_note(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.GetOccurrenceNoteRequest, dict]]): - The request object. Request to get the note to which the - specified occurrence is attached. - name (:class:`str`): - The name of the occurrence in the form of - ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_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_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.types.Note: - A type of analysis that can be done - for a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.GetOccurrenceNoteRequest): - request = grafeas.GetOccurrenceNoteRequest(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._client._transport._wrapped_methods[self._client._transport.get_occurrence_note] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def get_note(self, - request: Optional[Union[grafeas.GetNoteRequest, 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]] = (), - ) -> grafeas.Note: - r"""Gets the specified note. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - async def sample_get_note(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.GetNoteRequest( - name="name_value", - ) - - # Make the request - response = await client.get_note(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.GetNoteRequest, dict]]): - The request object. Request to get a note. - name (:class:`str`): - The name of the note in the form of - ``projects/[PROVIDER_ID]/notes/[NOTE_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_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.types.Note: - A type of analysis that can be done - for a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.GetNoteRequest): - request = grafeas.GetNoteRequest(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._client._transport._wrapped_methods[self._client._transport.get_note] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def list_notes(self, - request: Optional[Union[grafeas.ListNotesRequest, dict]] = None, - *, - parent: Optional[str] = None, - filter: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> pagers.ListNotesAsyncPager: - r"""Lists notes for the specified 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 grafeas import grafeas_v1 - - async def sample_list_notes(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.ListNotesRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_notes(request=request) - - # Handle the response - async for response in page_result: - print(response) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.ListNotesRequest, dict]]): - The request object. Request to list notes. - parent (:class:`str`): - The name of the project to list notes for in the form of - ``projects/[PROJECT_ID]``. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - filter (:class:`str`): - The filter expression. - This corresponds to the ``filter`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.services.grafeas.pagers.ListNotesAsyncPager: - Response for listing notes. - - 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, filter]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.ListNotesRequest): - request = grafeas.ListNotesRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if filter is not None: - request.filter = filter - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[self._client._transport.list_notes] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # 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.ListNotesAsyncPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def delete_note(self, - request: Optional[Union[grafeas.DeleteNoteRequest, 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 the specified note. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - async def sample_delete_note(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.DeleteNoteRequest( - name="name_value", - ) - - # Make the request - await client.delete_note(request=request) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.DeleteNoteRequest, dict]]): - The request object. Request to delete a note. - name (:class:`str`): - The name of the note in the form of - ``projects/[PROVIDER_ID]/notes/[NOTE_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_async.AsyncRetry): Designation of what errors, if any, - should be 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.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.DeleteNoteRequest): - request = grafeas.DeleteNoteRequest(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._client._transport._wrapped_methods[self._client._transport.delete_note] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - async def create_note(self, - request: Optional[Union[grafeas.CreateNoteRequest, dict]] = None, - *, - parent: Optional[str] = None, - note_id: Optional[str] = None, - note: Optional[grafeas.Note] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> grafeas.Note: - r"""Creates a new note. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - async def sample_create_note(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.CreateNoteRequest( - parent="parent_value", - note_id="note_id_value", - ) - - # Make the request - response = await client.create_note(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.CreateNoteRequest, dict]]): - The request object. Request to create a new note. - parent (:class:`str`): - The name of the project in the form of - ``projects/[PROJECT_ID]``, under which the note is to be - created. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - note_id (:class:`str`): - The ID to use for this note. - This corresponds to the ``note_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - note (:class:`grafeas.grafeas_v1.types.Note`): - The note to create. - This corresponds to the ``note`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.types.Note: - A type of analysis that can be done - for a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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, note_id, note]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.CreateNoteRequest): - request = grafeas.CreateNoteRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if note_id is not None: - request.note_id = note_id - if note is not None: - request.note = note - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[self._client._transport.create_note] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def batch_create_notes(self, - request: Optional[Union[grafeas.BatchCreateNotesRequest, dict]] = None, - *, - parent: Optional[str] = None, - notes: Optional[MutableMapping[str, grafeas.Note]] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> grafeas.BatchCreateNotesResponse: - r"""Creates new notes in batch. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - async def sample_batch_create_notes(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.BatchCreateNotesRequest( - parent="parent_value", - ) - - # Make the request - response = await client.batch_create_notes(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.BatchCreateNotesRequest, dict]]): - The request object. Request to create notes in batch. - parent (:class:`str`): - The name of the project in the form of - ``projects/[PROJECT_ID]``, under which the notes are to - be created. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - notes (:class:`MutableMapping[str, grafeas.grafeas_v1.types.Note]`): - The notes to create. Max allowed - length is 1000. - - This corresponds to the ``notes`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.types.BatchCreateNotesResponse: - Response for creating notes in batch. - """ - # Create or coerce a protobuf request object. - # - Quick 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, notes]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.BatchCreateNotesRequest): - request = grafeas.BatchCreateNotesRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - - if notes: - request.notes.update(notes) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[self._client._transport.batch_create_notes] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def update_note(self, - request: Optional[Union[grafeas.UpdateNoteRequest, dict]] = None, - *, - name: Optional[str] = None, - note: Optional[grafeas.Note] = 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]] = (), - ) -> grafeas.Note: - r"""Updates the specified note. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - async def sample_update_note(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.UpdateNoteRequest( - name="name_value", - ) - - # Make the request - response = await client.update_note(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.UpdateNoteRequest, dict]]): - The request object. Request to update a note. - name (:class:`str`): - The name of the note in the form of - ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - note (:class:`grafeas.grafeas_v1.types.Note`): - The updated note. - This corresponds to the ``note`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): - The fields to 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_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.types.Note: - A type of analysis that can be done - for a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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, note, 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.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.UpdateNoteRequest): - request = grafeas.UpdateNoteRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - if note is not None: - request.note = note - 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._client._transport._wrapped_methods[self._client._transport.update_note] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def list_note_occurrences(self, - request: Optional[Union[grafeas.ListNoteOccurrencesRequest, dict]] = None, - *, - name: Optional[str] = None, - filter: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> pagers.ListNoteOccurrencesAsyncPager: - r"""Lists occurrences referencing the specified note. - Provider projects can use this method to get all - occurrences across consumer projects referencing the - specified note. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - async def sample_list_note_occurrences(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.ListNoteOccurrencesRequest( - name="name_value", - ) - - # Make the request - page_result = client.list_note_occurrences(request=request) - - # Handle the response - async for response in page_result: - print(response) - - Args: - request (Optional[Union[grafeas.grafeas_v1.types.ListNoteOccurrencesRequest, dict]]): - The request object. Request to list occurrences for a - note. - name (:class:`str`): - The name of the note to list occurrences for in the form - of ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - filter (:class:`str`): - The filter expression. - This corresponds to the ``filter`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesAsyncPager: - Response for listing occurrences for - a note. - Iterating over this object will yield - results and resolve additional pages - automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([name, filter]) - if request is not None and has_flattened_params: - raise ValueError("If the `request` argument is set, then none of " - "the individual field arguments should be set.") - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.ListNoteOccurrencesRequest): - request = grafeas.ListNoteOccurrencesRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - if filter is not None: - request.filter = filter - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[self._client._transport.list_note_occurrences] - - # 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), - )), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # 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.ListNoteOccurrencesAsyncPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "GrafeasAsyncClient": - 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__ = ( - "GrafeasAsyncClient", -) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/client.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/client.py deleted file mode 100644 index ddafe8a8b439..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/client.py +++ /dev/null @@ -1,2196 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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, Callable, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from grafeas.grafeas_v1 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -from grafeas.grafeas_v1.services.grafeas import pagers -from grafeas.grafeas_v1.types import attestation -from grafeas.grafeas_v1.types import build -from grafeas.grafeas_v1.types import common -from grafeas.grafeas_v1.types import compliance -from grafeas.grafeas_v1.types import deployment -from grafeas.grafeas_v1.types import discovery -from grafeas.grafeas_v1.types import dsse_attestation -from grafeas.grafeas_v1.types import grafeas -from grafeas.grafeas_v1.types import image -from grafeas.grafeas_v1.types import package -from grafeas.grafeas_v1.types import sbom -from grafeas.grafeas_v1.types import upgrade -from grafeas.grafeas_v1.types import vex -from grafeas.grafeas_v1.types import vulnerability -from .transports.base import GrafeasTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import GrafeasGrpcTransport -from .transports.grpc_asyncio import GrafeasGrpcAsyncIOTransport -from .transports.rest import GrafeasRestTransport - - -class GrafeasClientMeta(type): - """Metaclass for the Grafeas 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[GrafeasTransport]] - _transport_registry["grpc"] = GrafeasGrpcTransport - _transport_registry["grpc_asyncio"] = GrafeasGrpcAsyncIOTransport - _transport_registry["rest"] = GrafeasRestTransport - - def get_transport_class(cls, - label: Optional[str] = None, - ) -> Type[GrafeasTransport]: - """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 GrafeasClient(metaclass=GrafeasClientMeta): - """`Grafeas `__ API. - - Retrieves analysis results of Cloud components such as Docker - container images. - - Analysis results are stored as a series of occurrences. An - ``Occurrence`` contains information about a specific analysis - instance on a resource. An occurrence refers to a ``Note``. A note - contains details describing the analysis and is generally stored in - a separate project, called a ``Provider``. Multiple occurrences can - refer to the same note. - - For example, an SSL vulnerability could affect multiple images. In - this case, there would be one note for the vulnerability and an - occurrence for each image with the vulnerability referring to that - note. - """ - - @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") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "containeranalysis.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "containeranalysis.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @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: - GrafeasClient: 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: - GrafeasClient: 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) -> GrafeasTransport: - """Returns the transport used by the client instance. - - Returns: - GrafeasTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def note_path(project: str,note: str,) -> str: - """Returns a fully-qualified note string.""" - return "projects/{project}/notes/{note}".format(project=project, note=note, ) - - @staticmethod - def parse_note_path(path: str) -> Dict[str,str]: - """Parses a note path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/notes/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def occurrence_path(project: str,occurrence: str,) -> str: - """Returns a fully-qualified occurrence string.""" - return "projects/{project}/occurrences/{occurrence}".format(project=project, occurrence=occurrence, ) - - @staticmethod - def parse_occurrence_path(path: str) -> Dict[str,str]: - """Parses a occurrence path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/occurrences/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def project_path(project: str,) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format(project=project, ) - - @staticmethod - def parse_project_path(path: str) -> Dict[str,str]: - """Parses a project path into its component segments.""" - m = re.match(r"^projects/(?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): - """Deprecated. 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. - """ - - warnings.warn("get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning) - 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 - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false").lower() - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - 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`") - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint(api_override, client_cert_source, universe_domain, use_mtls_endpoint): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or (use_mtls_endpoint == "auto" and client_cert_source): - _default_universe = GrafeasClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError(f"mTLS is not supported in any universe other than {_default_universe}.") - api_endpoint = GrafeasClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = GrafeasClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=universe_domain) - return api_endpoint - - @staticmethod - def _get_universe_domain(client_universe_domain: Optional[str], universe_domain_env: Optional[str]) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = GrafeasClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - @staticmethod - def _compare_universes(client_universe: str, - credentials: ga_credentials.Credentials) -> bool: - """Returns True iff the universe domains used by the client and credentials match. - - Args: - client_universe (str): The universe domain configured via the client options. - credentials (ga_credentials.Credentials): The credentials being used in the client. - - Returns: - bool: True iff client_universe matches the universe in credentials. - - Raises: - ValueError: when client_universe does not match the universe in credentials. - """ - - default_universe = GrafeasClient._DEFAULT_UNIVERSE - credentials_universe = getattr(credentials, "universe_domain", default_universe) - - if client_universe != credentials_universe: - raise ValueError("The configured universe domain " - f"({client_universe}) does not match the universe domain " - f"found in the credentials ({credentials_universe}). " - "If you haven't configured the universe domain explicitly, " - f"`{default_universe}` is the default.") - return True - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - self._is_universe_domain_valid = (self._is_universe_domain_valid or - GrafeasClient._compare_universes(self.universe_domain, self.transport._credentials)) - return self._is_universe_domain_valid - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__(self, *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[Union[str, GrafeasTransport, Callable[..., GrafeasTransport]]] = None, - client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the grafeas 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 (Optional[Union[str,GrafeasTransport,Callable[..., GrafeasTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the GrafeasTransport constructor. - 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. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "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). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS 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. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - 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. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict(self._client_options) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast(client_options_lib.ClientOptions, self._client_options) - - universe_domain_opt = getattr(self._client_options, 'universe_domain', None) - - self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = GrafeasClient._read_environment_variables() - self._client_cert_source = GrafeasClient._get_client_cert_source(self._client_options.client_cert_source, self._use_client_cert) - self._universe_domain = GrafeasClient._get_universe_domain(universe_domain_opt, self._universe_domain_env) - self._api_endpoint = None # updated below, depending on `transport` - - # Initialize the universe domain validation. - self._is_universe_domain_valid = False - - api_key_value = getattr(self._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. - transport_provided = isinstance(transport, GrafeasTransport) - if transport_provided: - # transport is a GrafeasTransport instance. - if credentials or self._client_options.credentials_file or api_key_value: - raise ValueError("When providing a transport instance, " - "provide its credentials directly.") - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(GrafeasTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = (self._api_endpoint or - GrafeasClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint)) - - if not transport_provided: - 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_init: Union[Type[GrafeasTransport], Callable[..., GrafeasTransport]] = ( - GrafeasClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., GrafeasTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - api_audience=self._client_options.api_audience, - ) - - def get_occurrence(self, - request: Optional[Union[grafeas.GetOccurrenceRequest, 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]] = (), - ) -> grafeas.Occurrence: - r"""Gets the specified occurrence. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - def sample_get_occurrence(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.GetOccurrenceRequest( - name="name_value", - ) - - # Make the request - response = client.get_occurrence(request=request) - - # Handle the response - print(response) - - Args: - request (Union[grafeas.grafeas_v1.types.GetOccurrenceRequest, dict]): - The request object. Request to get an occurrence. - name (str): - The name of the occurrence in the form of - ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_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: - grafeas.grafeas_v1.types.Occurrence: - An instance of an analysis type that - has been found on a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.GetOccurrenceRequest): - request = grafeas.GetOccurrenceRequest(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_occurrence] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_occurrences(self, - request: Optional[Union[grafeas.ListOccurrencesRequest, dict]] = None, - *, - parent: Optional[str] = None, - filter: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> pagers.ListOccurrencesPager: - r"""Lists occurrences for the specified 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 grafeas import grafeas_v1 - - def sample_list_occurrences(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.ListOccurrencesRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_occurrences(request=request) - - # Handle the response - for response in page_result: - print(response) - - Args: - request (Union[grafeas.grafeas_v1.types.ListOccurrencesRequest, dict]): - The request object. Request to list occurrences. - parent (str): - The name of the project to list occurrences for in the - form of ``projects/[PROJECT_ID]``. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - filter (str): - The filter expression. - This corresponds to the ``filter`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesPager: - Response for listing occurrences. - - 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, filter]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.ListOccurrencesRequest): - request = grafeas.ListOccurrencesRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if filter is not None: - request.filter = filter - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.list_occurrences] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # 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.ListOccurrencesPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def delete_occurrence(self, - request: Optional[Union[grafeas.DeleteOccurrenceRequest, 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 the specified occurrence. For example, use - this method to delete an occurrence when the occurrence - is no longer applicable for the given resource. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - def sample_delete_occurrence(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.DeleteOccurrenceRequest( - name="name_value", - ) - - # Make the request - client.delete_occurrence(request=request) - - Args: - request (Union[grafeas.grafeas_v1.types.DeleteOccurrenceRequest, dict]): - The request object. Request to delete an occurrence. - name (str): - The name of the occurrence in the form of - ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_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.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.DeleteOccurrenceRequest): - request = grafeas.DeleteOccurrenceRequest(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_occurrence] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - def create_occurrence(self, - request: Optional[Union[grafeas.CreateOccurrenceRequest, dict]] = None, - *, - parent: Optional[str] = None, - occurrence: Optional[grafeas.Occurrence] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> grafeas.Occurrence: - r"""Creates a new occurrence. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - def sample_create_occurrence(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.CreateOccurrenceRequest( - parent="parent_value", - ) - - # Make the request - response = client.create_occurrence(request=request) - - # Handle the response - print(response) - - Args: - request (Union[grafeas.grafeas_v1.types.CreateOccurrenceRequest, dict]): - The request object. Request to create a new occurrence. - parent (str): - The name of the project in the form of - ``projects/[PROJECT_ID]``, under which the occurrence is - to be created. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - occurrence (grafeas.grafeas_v1.types.Occurrence): - The occurrence to create. - This corresponds to the ``occurrence`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.types.Occurrence: - An instance of an analysis type that - has been found on a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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, occurrence]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.CreateOccurrenceRequest): - request = grafeas.CreateOccurrenceRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if occurrence is not None: - request.occurrence = occurrence - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.create_occurrence] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def batch_create_occurrences(self, - request: Optional[Union[grafeas.BatchCreateOccurrencesRequest, dict]] = None, - *, - parent: Optional[str] = None, - occurrences: Optional[MutableSequence[grafeas.Occurrence]] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> grafeas.BatchCreateOccurrencesResponse: - r"""Creates new occurrences in batch. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - def sample_batch_create_occurrences(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.BatchCreateOccurrencesRequest( - parent="parent_value", - ) - - # Make the request - response = client.batch_create_occurrences(request=request) - - # Handle the response - print(response) - - Args: - request (Union[grafeas.grafeas_v1.types.BatchCreateOccurrencesRequest, dict]): - The request object. Request to create occurrences in - batch. - parent (str): - The name of the project in the form of - ``projects/[PROJECT_ID]``, under which the occurrences - are to be created. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - occurrences (MutableSequence[grafeas.grafeas_v1.types.Occurrence]): - The occurrences to create. Max - allowed length is 1000. - - This corresponds to the ``occurrences`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse: - Response for creating occurrences in - batch. - - """ - # Create or coerce a protobuf request object. - # - Quick 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, occurrences]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.BatchCreateOccurrencesRequest): - request = grafeas.BatchCreateOccurrencesRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if occurrences is not None: - request.occurrences = occurrences - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.batch_create_occurrences] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def update_occurrence(self, - request: Optional[Union[grafeas.UpdateOccurrenceRequest, dict]] = None, - *, - name: Optional[str] = None, - occurrence: Optional[grafeas.Occurrence] = 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]] = (), - ) -> grafeas.Occurrence: - r"""Updates the specified occurrence. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - def sample_update_occurrence(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.UpdateOccurrenceRequest( - name="name_value", - ) - - # Make the request - response = client.update_occurrence(request=request) - - # Handle the response - print(response) - - Args: - request (Union[grafeas.grafeas_v1.types.UpdateOccurrenceRequest, dict]): - The request object. Request to update an occurrence. - name (str): - The name of the occurrence in the form of - ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - occurrence (grafeas.grafeas_v1.types.Occurrence): - The updated occurrence. - This corresponds to the ``occurrence`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - update_mask (google.protobuf.field_mask_pb2.FieldMask): - The fields to 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: - grafeas.grafeas_v1.types.Occurrence: - An instance of an analysis type that - has been found on a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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, occurrence, 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.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.UpdateOccurrenceRequest): - request = grafeas.UpdateOccurrenceRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - if occurrence is not None: - request.occurrence = occurrence - 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_occurrence] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def get_occurrence_note(self, - request: Optional[Union[grafeas.GetOccurrenceNoteRequest, 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]] = (), - ) -> grafeas.Note: - r"""Gets the note attached to the specified occurrence. - Consumer projects can use this method to get a note that - belongs to a provider 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 grafeas import grafeas_v1 - - def sample_get_occurrence_note(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.GetOccurrenceNoteRequest( - name="name_value", - ) - - # Make the request - response = client.get_occurrence_note(request=request) - - # Handle the response - print(response) - - Args: - request (Union[grafeas.grafeas_v1.types.GetOccurrenceNoteRequest, dict]): - The request object. Request to get the note to which the - specified occurrence is attached. - name (str): - The name of the occurrence in the form of - ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_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: - grafeas.grafeas_v1.types.Note: - A type of analysis that can be done - for a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.GetOccurrenceNoteRequest): - request = grafeas.GetOccurrenceNoteRequest(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_occurrence_note] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def get_note(self, - request: Optional[Union[grafeas.GetNoteRequest, 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]] = (), - ) -> grafeas.Note: - r"""Gets the specified note. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - def sample_get_note(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.GetNoteRequest( - name="name_value", - ) - - # Make the request - response = client.get_note(request=request) - - # Handle the response - print(response) - - Args: - request (Union[grafeas.grafeas_v1.types.GetNoteRequest, dict]): - The request object. Request to get a note. - name (str): - The name of the note in the form of - ``projects/[PROVIDER_ID]/notes/[NOTE_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: - grafeas.grafeas_v1.types.Note: - A type of analysis that can be done - for a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.GetNoteRequest): - request = grafeas.GetNoteRequest(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_note] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_notes(self, - request: Optional[Union[grafeas.ListNotesRequest, dict]] = None, - *, - parent: Optional[str] = None, - filter: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> pagers.ListNotesPager: - r"""Lists notes for the specified 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 grafeas import grafeas_v1 - - def sample_list_notes(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.ListNotesRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_notes(request=request) - - # Handle the response - for response in page_result: - print(response) - - Args: - request (Union[grafeas.grafeas_v1.types.ListNotesRequest, dict]): - The request object. Request to list notes. - parent (str): - The name of the project to list notes for in the form of - ``projects/[PROJECT_ID]``. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - filter (str): - The filter expression. - This corresponds to the ``filter`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.services.grafeas.pagers.ListNotesPager: - Response for listing notes. - - 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, filter]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.ListNotesRequest): - request = grafeas.ListNotesRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if filter is not None: - request.filter = filter - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.list_notes] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # 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.ListNotesPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def delete_note(self, - request: Optional[Union[grafeas.DeleteNoteRequest, 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 the specified note. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - def sample_delete_note(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.DeleteNoteRequest( - name="name_value", - ) - - # Make the request - client.delete_note(request=request) - - Args: - request (Union[grafeas.grafeas_v1.types.DeleteNoteRequest, dict]): - The request object. Request to delete a note. - name (str): - The name of the note in the form of - ``projects/[PROVIDER_ID]/notes/[NOTE_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.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.DeleteNoteRequest): - request = grafeas.DeleteNoteRequest(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_note] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - def create_note(self, - request: Optional[Union[grafeas.CreateNoteRequest, dict]] = None, - *, - parent: Optional[str] = None, - note_id: Optional[str] = None, - note: Optional[grafeas.Note] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> grafeas.Note: - r"""Creates a new note. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - def sample_create_note(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.CreateNoteRequest( - parent="parent_value", - note_id="note_id_value", - ) - - # Make the request - response = client.create_note(request=request) - - # Handle the response - print(response) - - Args: - request (Union[grafeas.grafeas_v1.types.CreateNoteRequest, dict]): - The request object. Request to create a new note. - parent (str): - The name of the project in the form of - ``projects/[PROJECT_ID]``, under which the note is to be - created. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - note_id (str): - The ID to use for this note. - This corresponds to the ``note_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - note (grafeas.grafeas_v1.types.Note): - The note to create. - This corresponds to the ``note`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.types.Note: - A type of analysis that can be done - for a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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, note_id, note]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.CreateNoteRequest): - request = grafeas.CreateNoteRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if note_id is not None: - request.note_id = note_id - if note is not None: - request.note = note - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.create_note] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def batch_create_notes(self, - request: Optional[Union[grafeas.BatchCreateNotesRequest, dict]] = None, - *, - parent: Optional[str] = None, - notes: Optional[MutableMapping[str, grafeas.Note]] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> grafeas.BatchCreateNotesResponse: - r"""Creates new notes in batch. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - def sample_batch_create_notes(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.BatchCreateNotesRequest( - parent="parent_value", - ) - - # Make the request - response = client.batch_create_notes(request=request) - - # Handle the response - print(response) - - Args: - request (Union[grafeas.grafeas_v1.types.BatchCreateNotesRequest, dict]): - The request object. Request to create notes in batch. - parent (str): - The name of the project in the form of - ``projects/[PROJECT_ID]``, under which the notes are to - be created. - - This corresponds to the ``parent`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - notes (MutableMapping[str, grafeas.grafeas_v1.types.Note]): - The notes to create. Max allowed - length is 1000. - - This corresponds to the ``notes`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.types.BatchCreateNotesResponse: - Response for creating notes in batch. - """ - # Create or coerce a protobuf request object. - # - Quick 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, notes]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.BatchCreateNotesRequest): - request = grafeas.BatchCreateNotesRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if parent is not None: - request.parent = parent - if notes is not None: - request.notes = notes - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.batch_create_notes] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def update_note(self, - request: Optional[Union[grafeas.UpdateNoteRequest, dict]] = None, - *, - name: Optional[str] = None, - note: Optional[grafeas.Note] = 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]] = (), - ) -> grafeas.Note: - r"""Updates the specified note. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - def sample_update_note(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.UpdateNoteRequest( - name="name_value", - ) - - # Make the request - response = client.update_note(request=request) - - # Handle the response - print(response) - - Args: - request (Union[grafeas.grafeas_v1.types.UpdateNoteRequest, dict]): - The request object. Request to update a note. - name (str): - The name of the note in the form of - ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - note (grafeas.grafeas_v1.types.Note): - The updated note. - This corresponds to the ``note`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - update_mask (google.protobuf.field_mask_pb2.FieldMask): - The fields to 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: - grafeas.grafeas_v1.types.Note: - A type of analysis that can be done - for a resource. - - """ - # Create or coerce a protobuf request object. - # - Quick 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, note, 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.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.UpdateNoteRequest): - request = grafeas.UpdateNoteRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - if note is not None: - request.note = note - 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_note] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_note_occurrences(self, - request: Optional[Union[grafeas.ListNoteOccurrencesRequest, dict]] = None, - *, - name: Optional[str] = None, - filter: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = (), - ) -> pagers.ListNoteOccurrencesPager: - r"""Lists occurrences referencing the specified note. - Provider projects can use this method to get all - occurrences across consumer projects referencing the - specified note. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from grafeas import grafeas_v1 - - def sample_list_note_occurrences(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.ListNoteOccurrencesRequest( - name="name_value", - ) - - # Make the request - page_result = client.list_note_occurrences(request=request) - - # Handle the response - for response in page_result: - print(response) - - Args: - request (Union[grafeas.grafeas_v1.types.ListNoteOccurrencesRequest, dict]): - The request object. Request to list occurrences for a - note. - name (str): - The name of the note to list occurrences for in the form - of ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. - - This corresponds to the ``name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - filter (str): - The filter expression. - This corresponds to the ``filter`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesPager: - Response for listing occurrences for - a note. - Iterating over this object will yield - results and resolve additional pages - automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - has_flattened_params = any([name, filter]) - if request is not None and has_flattened_params: - raise ValueError('If the `request` argument is set, then none of ' - 'the individual field arguments should be set.') - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, grafeas.ListNoteOccurrencesRequest): - request = grafeas.ListNoteOccurrencesRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if name is not None: - request.name = name - if filter is not None: - request.filter = filter - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.list_note_occurrences] - - # 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), - )), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # 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.ListNoteOccurrencesPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "GrafeasClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - - - - - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) - - -__all__ = ( - "GrafeasClient", -) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/pagers.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/pagers.py deleted file mode 100644 index b905bf6d42fb..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/pagers.py +++ /dev/null @@ -1,432 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import retry_async as retries_async -from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator, Union -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] - OptionalAsyncRetry = Union[retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore - -from grafeas.grafeas_v1.types import grafeas - - -class ListOccurrencesPager: - """A pager for iterating through ``list_occurrences`` requests. - - This class thinly wraps an initial - :class:`grafeas.grafeas_v1.types.ListOccurrencesResponse` object, and - provides an ``__iter__`` method to iterate through its - ``occurrences`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``ListOccurrences`` requests and continue to iterate - through the ``occurrences`` field on the - corresponding responses. - - All the usual :class:`grafeas.grafeas_v1.types.ListOccurrencesResponse` - 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[..., grafeas.ListOccurrencesResponse], - request: grafeas.ListOccurrencesRequest, - response: grafeas.ListOccurrencesResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (grafeas.grafeas_v1.types.ListOccurrencesRequest): - The initial request object. - response (grafeas.grafeas_v1.types.ListOccurrencesResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = grafeas.ListOccurrencesRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[grafeas.ListOccurrencesResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method(self._request, retry=self._retry, timeout=self._timeout, metadata=self._metadata) - yield self._response - - def __iter__(self) -> Iterator[grafeas.Occurrence]: - for page in self.pages: - yield from page.occurrences - - def __repr__(self) -> str: - return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) - - -class ListOccurrencesAsyncPager: - """A pager for iterating through ``list_occurrences`` requests. - - This class thinly wraps an initial - :class:`grafeas.grafeas_v1.types.ListOccurrencesResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``occurrences`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``ListOccurrences`` requests and continue to iterate - through the ``occurrences`` field on the - corresponding responses. - - All the usual :class:`grafeas.grafeas_v1.types.ListOccurrencesResponse` - 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[grafeas.ListOccurrencesResponse]], - request: grafeas.ListOccurrencesRequest, - response: grafeas.ListOccurrencesResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (grafeas.grafeas_v1.types.ListOccurrencesRequest): - The initial request object. - response (grafeas.grafeas_v1.types.ListOccurrencesResponse): - The initial response object. - retry (google.api_core.retry.AsyncRetry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = grafeas.ListOccurrencesRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages(self) -> AsyncIterator[grafeas.ListOccurrencesResponse]: - 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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) - yield self._response - def __aiter__(self) -> AsyncIterator[grafeas.Occurrence]: - async def async_generator(): - async for page in self.pages: - for response in page.occurrences: - yield response - - return async_generator() - - def __repr__(self) -> str: - return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) - - -class ListNotesPager: - """A pager for iterating through ``list_notes`` requests. - - This class thinly wraps an initial - :class:`grafeas.grafeas_v1.types.ListNotesResponse` object, and - provides an ``__iter__`` method to iterate through its - ``notes`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``ListNotes`` requests and continue to iterate - through the ``notes`` field on the - corresponding responses. - - All the usual :class:`grafeas.grafeas_v1.types.ListNotesResponse` - 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[..., grafeas.ListNotesResponse], - request: grafeas.ListNotesRequest, - response: grafeas.ListNotesResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (grafeas.grafeas_v1.types.ListNotesRequest): - The initial request object. - response (grafeas.grafeas_v1.types.ListNotesResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = grafeas.ListNotesRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[grafeas.ListNotesResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method(self._request, retry=self._retry, timeout=self._timeout, metadata=self._metadata) - yield self._response - - def __iter__(self) -> Iterator[grafeas.Note]: - for page in self.pages: - yield from page.notes - - def __repr__(self) -> str: - return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) - - -class ListNotesAsyncPager: - """A pager for iterating through ``list_notes`` requests. - - This class thinly wraps an initial - :class:`grafeas.grafeas_v1.types.ListNotesResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``notes`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``ListNotes`` requests and continue to iterate - through the ``notes`` field on the - corresponding responses. - - All the usual :class:`grafeas.grafeas_v1.types.ListNotesResponse` - 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[grafeas.ListNotesResponse]], - request: grafeas.ListNotesRequest, - response: grafeas.ListNotesResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (grafeas.grafeas_v1.types.ListNotesRequest): - The initial request object. - response (grafeas.grafeas_v1.types.ListNotesResponse): - The initial response object. - retry (google.api_core.retry.AsyncRetry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = grafeas.ListNotesRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages(self) -> AsyncIterator[grafeas.ListNotesResponse]: - 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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) - yield self._response - def __aiter__(self) -> AsyncIterator[grafeas.Note]: - async def async_generator(): - async for page in self.pages: - for response in page.notes: - yield response - - return async_generator() - - def __repr__(self) -> str: - return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) - - -class ListNoteOccurrencesPager: - """A pager for iterating through ``list_note_occurrences`` requests. - - This class thinly wraps an initial - :class:`grafeas.grafeas_v1.types.ListNoteOccurrencesResponse` object, and - provides an ``__iter__`` method to iterate through its - ``occurrences`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``ListNoteOccurrences`` requests and continue to iterate - through the ``occurrences`` field on the - corresponding responses. - - All the usual :class:`grafeas.grafeas_v1.types.ListNoteOccurrencesResponse` - 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[..., grafeas.ListNoteOccurrencesResponse], - request: grafeas.ListNoteOccurrencesRequest, - response: grafeas.ListNoteOccurrencesResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (grafeas.grafeas_v1.types.ListNoteOccurrencesRequest): - The initial request object. - response (grafeas.grafeas_v1.types.ListNoteOccurrencesResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = grafeas.ListNoteOccurrencesRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[grafeas.ListNoteOccurrencesResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method(self._request, retry=self._retry, timeout=self._timeout, metadata=self._metadata) - yield self._response - - def __iter__(self) -> Iterator[grafeas.Occurrence]: - for page in self.pages: - yield from page.occurrences - - def __repr__(self) -> str: - return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) - - -class ListNoteOccurrencesAsyncPager: - """A pager for iterating through ``list_note_occurrences`` requests. - - This class thinly wraps an initial - :class:`grafeas.grafeas_v1.types.ListNoteOccurrencesResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``occurrences`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``ListNoteOccurrences`` requests and continue to iterate - through the ``occurrences`` field on the - corresponding responses. - - All the usual :class:`grafeas.grafeas_v1.types.ListNoteOccurrencesResponse` - 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[grafeas.ListNoteOccurrencesResponse]], - request: grafeas.ListNoteOccurrencesRequest, - response: grafeas.ListNoteOccurrencesResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, str]] = ()): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (grafeas.grafeas_v1.types.ListNoteOccurrencesRequest): - The initial request object. - response (grafeas.grafeas_v1.types.ListNoteOccurrencesResponse): - The initial response object. - retry (google.api_core.retry.AsyncRetry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - """ - self._method = method - self._request = grafeas.ListNoteOccurrencesRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages(self) -> AsyncIterator[grafeas.ListNoteOccurrencesResponse]: - 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, retry=self._retry, timeout=self._timeout, metadata=self._metadata) - yield self._response - def __aiter__(self) -> AsyncIterator[grafeas.Occurrence]: - async def async_generator(): - async for page in self.pages: - for response in page.occurrences: - 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/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/README.rst b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/README.rst deleted file mode 100644 index 1085202fe2c8..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/README.rst +++ /dev/null @@ -1,9 +0,0 @@ - -transport inheritance structure -_______________________________ - -`GrafeasTransport` is the ABC for all transports. -- public child `GrafeasGrpcTransport` for sync gRPC transport (defined in `grpc.py`). -- public child `GrafeasGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). -- private child `_BaseGrafeasRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). -- public child `GrafeasRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/__init__.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/__init__.py deleted file mode 100644 index af77bbdd97ec..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/__init__.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 GrafeasTransport -from .grpc import GrafeasGrpcTransport -from .grpc_asyncio import GrafeasGrpcAsyncIOTransport -from .rest import GrafeasRestTransport -from .rest import GrafeasRestInterceptor - - -# Compile a registry of transports. -_transport_registry = OrderedDict() # type: Dict[str, Type[GrafeasTransport]] -_transport_registry['grpc'] = GrafeasGrpcTransport -_transport_registry['grpc_asyncio'] = GrafeasGrpcAsyncIOTransport -_transport_registry['rest'] = GrafeasRestTransport - -__all__ = ( - 'GrafeasTransport', - 'GrafeasGrpcTransport', - 'GrafeasGrpcAsyncIOTransport', - 'GrafeasRestTransport', - 'GrafeasRestInterceptor', -) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/base.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/base.py deleted file mode 100644 index 6fbf36ad7b3d..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/base.py +++ /dev/null @@ -1,416 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 grafeas.grafeas_v1 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore - -from google.protobuf import empty_pb2 # type: ignore -from grafeas.grafeas_v1.types import grafeas - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) - - -class GrafeasTransport(abc.ABC): - """Abstract transport class for Grafeas.""" - - AUTH_SCOPES = ( - ) - - DEFAULT_HOST: str = 'containeranalysis.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 (default: 'containeranalysis.googleapis.com'). - 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 not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # 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 and not self._ignore_credentials: - 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 - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.get_occurrence: gapic_v1.method.wrap_method( - self.get_occurrence, - default_retry=retries.Retry( - initial=0.1, - maximum=60.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=30.0, - ), - default_timeout=30.0, - client_info=client_info, - ), - self.list_occurrences: gapic_v1.method.wrap_method( - self.list_occurrences, - default_retry=retries.Retry( - initial=0.1, - maximum=60.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=30.0, - ), - default_timeout=30.0, - client_info=client_info, - ), - self.delete_occurrence: gapic_v1.method.wrap_method( - self.delete_occurrence, - default_retry=retries.Retry( - initial=0.1, - maximum=60.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=30.0, - ), - default_timeout=30.0, - client_info=client_info, - ), - self.create_occurrence: gapic_v1.method.wrap_method( - self.create_occurrence, - default_timeout=30.0, - client_info=client_info, - ), - self.batch_create_occurrences: gapic_v1.method.wrap_method( - self.batch_create_occurrences, - default_timeout=30.0, - client_info=client_info, - ), - self.update_occurrence: gapic_v1.method.wrap_method( - self.update_occurrence, - default_timeout=30.0, - client_info=client_info, - ), - self.get_occurrence_note: gapic_v1.method.wrap_method( - self.get_occurrence_note, - default_retry=retries.Retry( - initial=0.1, - maximum=60.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=30.0, - ), - default_timeout=30.0, - client_info=client_info, - ), - self.get_note: gapic_v1.method.wrap_method( - self.get_note, - default_retry=retries.Retry( - initial=0.1, - maximum=60.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=30.0, - ), - default_timeout=30.0, - client_info=client_info, - ), - self.list_notes: gapic_v1.method.wrap_method( - self.list_notes, - default_retry=retries.Retry( - initial=0.1, - maximum=60.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=30.0, - ), - default_timeout=30.0, - client_info=client_info, - ), - self.delete_note: gapic_v1.method.wrap_method( - self.delete_note, - default_retry=retries.Retry( - initial=0.1, - maximum=60.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=30.0, - ), - default_timeout=30.0, - client_info=client_info, - ), - self.create_note: gapic_v1.method.wrap_method( - self.create_note, - default_timeout=30.0, - client_info=client_info, - ), - self.batch_create_notes: gapic_v1.method.wrap_method( - self.batch_create_notes, - default_timeout=30.0, - client_info=client_info, - ), - self.update_note: gapic_v1.method.wrap_method( - self.update_note, - default_timeout=30.0, - client_info=client_info, - ), - self.list_note_occurrences: gapic_v1.method.wrap_method( - self.list_note_occurrences, - default_retry=retries.Retry( - initial=0.1, - maximum=60.0, - multiplier=1.3, - predicate=retries.if_exception_type( - core_exceptions.DeadlineExceeded, - core_exceptions.ServiceUnavailable, - ), - deadline=30.0, - ), - default_timeout=30.0, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def get_occurrence(self) -> Callable[ - [grafeas.GetOccurrenceRequest], - Union[ - grafeas.Occurrence, - Awaitable[grafeas.Occurrence] - ]]: - raise NotImplementedError() - - @property - def list_occurrences(self) -> Callable[ - [grafeas.ListOccurrencesRequest], - Union[ - grafeas.ListOccurrencesResponse, - Awaitable[grafeas.ListOccurrencesResponse] - ]]: - raise NotImplementedError() - - @property - def delete_occurrence(self) -> Callable[ - [grafeas.DeleteOccurrenceRequest], - Union[ - empty_pb2.Empty, - Awaitable[empty_pb2.Empty] - ]]: - raise NotImplementedError() - - @property - def create_occurrence(self) -> Callable[ - [grafeas.CreateOccurrenceRequest], - Union[ - grafeas.Occurrence, - Awaitable[grafeas.Occurrence] - ]]: - raise NotImplementedError() - - @property - def batch_create_occurrences(self) -> Callable[ - [grafeas.BatchCreateOccurrencesRequest], - Union[ - grafeas.BatchCreateOccurrencesResponse, - Awaitable[grafeas.BatchCreateOccurrencesResponse] - ]]: - raise NotImplementedError() - - @property - def update_occurrence(self) -> Callable[ - [grafeas.UpdateOccurrenceRequest], - Union[ - grafeas.Occurrence, - Awaitable[grafeas.Occurrence] - ]]: - raise NotImplementedError() - - @property - def get_occurrence_note(self) -> Callable[ - [grafeas.GetOccurrenceNoteRequest], - Union[ - grafeas.Note, - Awaitable[grafeas.Note] - ]]: - raise NotImplementedError() - - @property - def get_note(self) -> Callable[ - [grafeas.GetNoteRequest], - Union[ - grafeas.Note, - Awaitable[grafeas.Note] - ]]: - raise NotImplementedError() - - @property - def list_notes(self) -> Callable[ - [grafeas.ListNotesRequest], - Union[ - grafeas.ListNotesResponse, - Awaitable[grafeas.ListNotesResponse] - ]]: - raise NotImplementedError() - - @property - def delete_note(self) -> Callable[ - [grafeas.DeleteNoteRequest], - Union[ - empty_pb2.Empty, - Awaitable[empty_pb2.Empty] - ]]: - raise NotImplementedError() - - @property - def create_note(self) -> Callable[ - [grafeas.CreateNoteRequest], - Union[ - grafeas.Note, - Awaitable[grafeas.Note] - ]]: - raise NotImplementedError() - - @property - def batch_create_notes(self) -> Callable[ - [grafeas.BatchCreateNotesRequest], - Union[ - grafeas.BatchCreateNotesResponse, - Awaitable[grafeas.BatchCreateNotesResponse] - ]]: - raise NotImplementedError() - - @property - def update_note(self) -> Callable[ - [grafeas.UpdateNoteRequest], - Union[ - grafeas.Note, - Awaitable[grafeas.Note] - ]]: - raise NotImplementedError() - - @property - def list_note_occurrences(self) -> Callable[ - [grafeas.ListNoteOccurrencesRequest], - Union[ - grafeas.ListNoteOccurrencesResponse, - Awaitable[grafeas.ListNoteOccurrencesResponse] - ]]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ( - 'GrafeasTransport', -) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc.py deleted file mode 100644 index 5c1c9e6c0bde..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc.py +++ /dev/null @@ -1,631 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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.protobuf import empty_pb2 # type: ignore -from grafeas.grafeas_v1.types import grafeas -from .base import GrafeasTransport, DEFAULT_CLIENT_INFO - - -class GrafeasGrpcTransport(GrafeasTransport): - """gRPC backend transport for Grafeas. - - `Grafeas `__ API. - - Retrieves analysis results of Cloud components such as Docker - container images. - - Analysis results are stored as a series of occurrences. An - ``Occurrence`` contains information about a specific analysis - instance on a resource. An occurrence refers to a ``Note``. A note - contains details describing the analysis and is generally stored in - a separate project, called a ``Provider``. Multiple occurrences can - refer to the same note. - - For example, an SSL vulnerability could affect multiple images. In - this case, there would be one note for the vulnerability and an - occurrence for each image with the vulnerability referring to that - note. - - 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 = 'containeranalysis.googleapis.com', - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[grpc.Channel, Callable[..., 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 (default: 'containeranalysis.googleapis.com'). - 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 a ``channel`` instance 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 a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # 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: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - 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 = 'containeranalysis.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 get_occurrence(self) -> Callable[ - [grafeas.GetOccurrenceRequest], - grafeas.Occurrence]: - r"""Return a callable for the get occurrence method over gRPC. - - Gets the specified occurrence. - - Returns: - Callable[[~.GetOccurrenceRequest], - ~.Occurrence]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_occurrence' not in self._stubs: - self._stubs['get_occurrence'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/GetOccurrence', - request_serializer=grafeas.GetOccurrenceRequest.serialize, - response_deserializer=grafeas.Occurrence.deserialize, - ) - return self._stubs['get_occurrence'] - - @property - def list_occurrences(self) -> Callable[ - [grafeas.ListOccurrencesRequest], - grafeas.ListOccurrencesResponse]: - r"""Return a callable for the list occurrences method over gRPC. - - Lists occurrences for the specified project. - - Returns: - Callable[[~.ListOccurrencesRequest], - ~.ListOccurrencesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_occurrences' not in self._stubs: - self._stubs['list_occurrences'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/ListOccurrences', - request_serializer=grafeas.ListOccurrencesRequest.serialize, - response_deserializer=grafeas.ListOccurrencesResponse.deserialize, - ) - return self._stubs['list_occurrences'] - - @property - def delete_occurrence(self) -> Callable[ - [grafeas.DeleteOccurrenceRequest], - empty_pb2.Empty]: - r"""Return a callable for the delete occurrence method over gRPC. - - Deletes the specified occurrence. For example, use - this method to delete an occurrence when the occurrence - is no longer applicable for the given resource. - - Returns: - Callable[[~.DeleteOccurrenceRequest], - ~.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_occurrence' not in self._stubs: - self._stubs['delete_occurrence'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/DeleteOccurrence', - request_serializer=grafeas.DeleteOccurrenceRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - return self._stubs['delete_occurrence'] - - @property - def create_occurrence(self) -> Callable[ - [grafeas.CreateOccurrenceRequest], - grafeas.Occurrence]: - r"""Return a callable for the create occurrence method over gRPC. - - Creates a new occurrence. - - Returns: - Callable[[~.CreateOccurrenceRequest], - ~.Occurrence]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_occurrence' not in self._stubs: - self._stubs['create_occurrence'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/CreateOccurrence', - request_serializer=grafeas.CreateOccurrenceRequest.serialize, - response_deserializer=grafeas.Occurrence.deserialize, - ) - return self._stubs['create_occurrence'] - - @property - def batch_create_occurrences(self) -> Callable[ - [grafeas.BatchCreateOccurrencesRequest], - grafeas.BatchCreateOccurrencesResponse]: - r"""Return a callable for the batch create occurrences method over gRPC. - - Creates new occurrences in batch. - - Returns: - Callable[[~.BatchCreateOccurrencesRequest], - ~.BatchCreateOccurrencesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_create_occurrences' not in self._stubs: - self._stubs['batch_create_occurrences'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/BatchCreateOccurrences', - request_serializer=grafeas.BatchCreateOccurrencesRequest.serialize, - response_deserializer=grafeas.BatchCreateOccurrencesResponse.deserialize, - ) - return self._stubs['batch_create_occurrences'] - - @property - def update_occurrence(self) -> Callable[ - [grafeas.UpdateOccurrenceRequest], - grafeas.Occurrence]: - r"""Return a callable for the update occurrence method over gRPC. - - Updates the specified occurrence. - - Returns: - Callable[[~.UpdateOccurrenceRequest], - ~.Occurrence]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_occurrence' not in self._stubs: - self._stubs['update_occurrence'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/UpdateOccurrence', - request_serializer=grafeas.UpdateOccurrenceRequest.serialize, - response_deserializer=grafeas.Occurrence.deserialize, - ) - return self._stubs['update_occurrence'] - - @property - def get_occurrence_note(self) -> Callable[ - [grafeas.GetOccurrenceNoteRequest], - grafeas.Note]: - r"""Return a callable for the get occurrence note method over gRPC. - - Gets the note attached to the specified occurrence. - Consumer projects can use this method to get a note that - belongs to a provider project. - - Returns: - Callable[[~.GetOccurrenceNoteRequest], - ~.Note]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_occurrence_note' not in self._stubs: - self._stubs['get_occurrence_note'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/GetOccurrenceNote', - request_serializer=grafeas.GetOccurrenceNoteRequest.serialize, - response_deserializer=grafeas.Note.deserialize, - ) - return self._stubs['get_occurrence_note'] - - @property - def get_note(self) -> Callable[ - [grafeas.GetNoteRequest], - grafeas.Note]: - r"""Return a callable for the get note method over gRPC. - - Gets the specified note. - - Returns: - Callable[[~.GetNoteRequest], - ~.Note]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_note' not in self._stubs: - self._stubs['get_note'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/GetNote', - request_serializer=grafeas.GetNoteRequest.serialize, - response_deserializer=grafeas.Note.deserialize, - ) - return self._stubs['get_note'] - - @property - def list_notes(self) -> Callable[ - [grafeas.ListNotesRequest], - grafeas.ListNotesResponse]: - r"""Return a callable for the list notes method over gRPC. - - Lists notes for the specified project. - - Returns: - Callable[[~.ListNotesRequest], - ~.ListNotesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_notes' not in self._stubs: - self._stubs['list_notes'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/ListNotes', - request_serializer=grafeas.ListNotesRequest.serialize, - response_deserializer=grafeas.ListNotesResponse.deserialize, - ) - return self._stubs['list_notes'] - - @property - def delete_note(self) -> Callable[ - [grafeas.DeleteNoteRequest], - empty_pb2.Empty]: - r"""Return a callable for the delete note method over gRPC. - - Deletes the specified note. - - Returns: - Callable[[~.DeleteNoteRequest], - ~.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_note' not in self._stubs: - self._stubs['delete_note'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/DeleteNote', - request_serializer=grafeas.DeleteNoteRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - return self._stubs['delete_note'] - - @property - def create_note(self) -> Callable[ - [grafeas.CreateNoteRequest], - grafeas.Note]: - r"""Return a callable for the create note method over gRPC. - - Creates a new note. - - Returns: - Callable[[~.CreateNoteRequest], - ~.Note]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_note' not in self._stubs: - self._stubs['create_note'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/CreateNote', - request_serializer=grafeas.CreateNoteRequest.serialize, - response_deserializer=grafeas.Note.deserialize, - ) - return self._stubs['create_note'] - - @property - def batch_create_notes(self) -> Callable[ - [grafeas.BatchCreateNotesRequest], - grafeas.BatchCreateNotesResponse]: - r"""Return a callable for the batch create notes method over gRPC. - - Creates new notes in batch. - - Returns: - Callable[[~.BatchCreateNotesRequest], - ~.BatchCreateNotesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_create_notes' not in self._stubs: - self._stubs['batch_create_notes'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/BatchCreateNotes', - request_serializer=grafeas.BatchCreateNotesRequest.serialize, - response_deserializer=grafeas.BatchCreateNotesResponse.deserialize, - ) - return self._stubs['batch_create_notes'] - - @property - def update_note(self) -> Callable[ - [grafeas.UpdateNoteRequest], - grafeas.Note]: - r"""Return a callable for the update note method over gRPC. - - Updates the specified note. - - Returns: - Callable[[~.UpdateNoteRequest], - ~.Note]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_note' not in self._stubs: - self._stubs['update_note'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/UpdateNote', - request_serializer=grafeas.UpdateNoteRequest.serialize, - response_deserializer=grafeas.Note.deserialize, - ) - return self._stubs['update_note'] - - @property - def list_note_occurrences(self) -> Callable[ - [grafeas.ListNoteOccurrencesRequest], - grafeas.ListNoteOccurrencesResponse]: - r"""Return a callable for the list note occurrences method over gRPC. - - Lists occurrences referencing the specified note. - Provider projects can use this method to get all - occurrences across consumer projects referencing the - specified note. - - Returns: - Callable[[~.ListNoteOccurrencesRequest], - ~.ListNoteOccurrencesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_note_occurrences' not in self._stubs: - self._stubs['list_note_occurrences'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/ListNoteOccurrences', - request_serializer=grafeas.ListNoteOccurrencesRequest.serialize, - response_deserializer=grafeas.ListNoteOccurrencesResponse.deserialize, - ) - return self._stubs['list_note_occurrences'] - - def close(self): - self.grpc_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ( - 'GrafeasGrpcTransport', -) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py deleted file mode 100644 index b927b81553b6..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py +++ /dev/null @@ -1,797 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 inspect -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 exceptions as core_exceptions -from google.api_core import retry_async as retries -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.protobuf import empty_pb2 # type: ignore -from grafeas.grafeas_v1.types import grafeas -from .base import GrafeasTransport, DEFAULT_CLIENT_INFO -from .grpc import GrafeasGrpcTransport - - -class GrafeasGrpcAsyncIOTransport(GrafeasTransport): - """gRPC AsyncIO backend transport for Grafeas. - - `Grafeas `__ API. - - Retrieves analysis results of Cloud components such as Docker - container images. - - Analysis results are stored as a series of occurrences. An - ``Occurrence`` contains information about a specific analysis - instance on a resource. An occurrence refers to a ``Note``. A note - contains details describing the analysis and is generally stored in - a separate project, called a ``Provider``. Multiple occurrences can - refer to the same note. - - For example, an SSL vulnerability could affect multiple images. In - this case, there would be one note for the vulnerability and an - occurrence for each image with the vulnerability referring to that - note. - - 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 = 'containeranalysis.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`. - 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 = 'containeranalysis.googleapis.com', - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[aio.Channel, Callable[..., 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 (default: 'containeranalysis.googleapis.com'). - 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 a ``channel`` instance 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 a ``channel`` instance 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[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - 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 a ``channel`` instance 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 a ``channel`` instance 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 isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # 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: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - 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._wrap_with_kind = "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters - 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 get_occurrence(self) -> Callable[ - [grafeas.GetOccurrenceRequest], - Awaitable[grafeas.Occurrence]]: - r"""Return a callable for the get occurrence method over gRPC. - - Gets the specified occurrence. - - Returns: - Callable[[~.GetOccurrenceRequest], - Awaitable[~.Occurrence]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_occurrence' not in self._stubs: - self._stubs['get_occurrence'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/GetOccurrence', - request_serializer=grafeas.GetOccurrenceRequest.serialize, - response_deserializer=grafeas.Occurrence.deserialize, - ) - return self._stubs['get_occurrence'] - - @property - def list_occurrences(self) -> Callable[ - [grafeas.ListOccurrencesRequest], - Awaitable[grafeas.ListOccurrencesResponse]]: - r"""Return a callable for the list occurrences method over gRPC. - - Lists occurrences for the specified project. - - Returns: - Callable[[~.ListOccurrencesRequest], - Awaitable[~.ListOccurrencesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_occurrences' not in self._stubs: - self._stubs['list_occurrences'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/ListOccurrences', - request_serializer=grafeas.ListOccurrencesRequest.serialize, - response_deserializer=grafeas.ListOccurrencesResponse.deserialize, - ) - return self._stubs['list_occurrences'] - - @property - def delete_occurrence(self) -> Callable[ - [grafeas.DeleteOccurrenceRequest], - Awaitable[empty_pb2.Empty]]: - r"""Return a callable for the delete occurrence method over gRPC. - - Deletes the specified occurrence. For example, use - this method to delete an occurrence when the occurrence - is no longer applicable for the given resource. - - Returns: - Callable[[~.DeleteOccurrenceRequest], - 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_occurrence' not in self._stubs: - self._stubs['delete_occurrence'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/DeleteOccurrence', - request_serializer=grafeas.DeleteOccurrenceRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - return self._stubs['delete_occurrence'] - - @property - def create_occurrence(self) -> Callable[ - [grafeas.CreateOccurrenceRequest], - Awaitable[grafeas.Occurrence]]: - r"""Return a callable for the create occurrence method over gRPC. - - Creates a new occurrence. - - Returns: - Callable[[~.CreateOccurrenceRequest], - Awaitable[~.Occurrence]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_occurrence' not in self._stubs: - self._stubs['create_occurrence'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/CreateOccurrence', - request_serializer=grafeas.CreateOccurrenceRequest.serialize, - response_deserializer=grafeas.Occurrence.deserialize, - ) - return self._stubs['create_occurrence'] - - @property - def batch_create_occurrences(self) -> Callable[ - [grafeas.BatchCreateOccurrencesRequest], - Awaitable[grafeas.BatchCreateOccurrencesResponse]]: - r"""Return a callable for the batch create occurrences method over gRPC. - - Creates new occurrences in batch. - - Returns: - Callable[[~.BatchCreateOccurrencesRequest], - Awaitable[~.BatchCreateOccurrencesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_create_occurrences' not in self._stubs: - self._stubs['batch_create_occurrences'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/BatchCreateOccurrences', - request_serializer=grafeas.BatchCreateOccurrencesRequest.serialize, - response_deserializer=grafeas.BatchCreateOccurrencesResponse.deserialize, - ) - return self._stubs['batch_create_occurrences'] - - @property - def update_occurrence(self) -> Callable[ - [grafeas.UpdateOccurrenceRequest], - Awaitable[grafeas.Occurrence]]: - r"""Return a callable for the update occurrence method over gRPC. - - Updates the specified occurrence. - - Returns: - Callable[[~.UpdateOccurrenceRequest], - Awaitable[~.Occurrence]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_occurrence' not in self._stubs: - self._stubs['update_occurrence'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/UpdateOccurrence', - request_serializer=grafeas.UpdateOccurrenceRequest.serialize, - response_deserializer=grafeas.Occurrence.deserialize, - ) - return self._stubs['update_occurrence'] - - @property - def get_occurrence_note(self) -> Callable[ - [grafeas.GetOccurrenceNoteRequest], - Awaitable[grafeas.Note]]: - r"""Return a callable for the get occurrence note method over gRPC. - - Gets the note attached to the specified occurrence. - Consumer projects can use this method to get a note that - belongs to a provider project. - - Returns: - Callable[[~.GetOccurrenceNoteRequest], - Awaitable[~.Note]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_occurrence_note' not in self._stubs: - self._stubs['get_occurrence_note'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/GetOccurrenceNote', - request_serializer=grafeas.GetOccurrenceNoteRequest.serialize, - response_deserializer=grafeas.Note.deserialize, - ) - return self._stubs['get_occurrence_note'] - - @property - def get_note(self) -> Callable[ - [grafeas.GetNoteRequest], - Awaitable[grafeas.Note]]: - r"""Return a callable for the get note method over gRPC. - - Gets the specified note. - - Returns: - Callable[[~.GetNoteRequest], - Awaitable[~.Note]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_note' not in self._stubs: - self._stubs['get_note'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/GetNote', - request_serializer=grafeas.GetNoteRequest.serialize, - response_deserializer=grafeas.Note.deserialize, - ) - return self._stubs['get_note'] - - @property - def list_notes(self) -> Callable[ - [grafeas.ListNotesRequest], - Awaitable[grafeas.ListNotesResponse]]: - r"""Return a callable for the list notes method over gRPC. - - Lists notes for the specified project. - - Returns: - Callable[[~.ListNotesRequest], - Awaitable[~.ListNotesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_notes' not in self._stubs: - self._stubs['list_notes'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/ListNotes', - request_serializer=grafeas.ListNotesRequest.serialize, - response_deserializer=grafeas.ListNotesResponse.deserialize, - ) - return self._stubs['list_notes'] - - @property - def delete_note(self) -> Callable[ - [grafeas.DeleteNoteRequest], - Awaitable[empty_pb2.Empty]]: - r"""Return a callable for the delete note method over gRPC. - - Deletes the specified note. - - Returns: - Callable[[~.DeleteNoteRequest], - 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_note' not in self._stubs: - self._stubs['delete_note'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/DeleteNote', - request_serializer=grafeas.DeleteNoteRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - return self._stubs['delete_note'] - - @property - def create_note(self) -> Callable[ - [grafeas.CreateNoteRequest], - Awaitable[grafeas.Note]]: - r"""Return a callable for the create note method over gRPC. - - Creates a new note. - - Returns: - Callable[[~.CreateNoteRequest], - Awaitable[~.Note]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_note' not in self._stubs: - self._stubs['create_note'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/CreateNote', - request_serializer=grafeas.CreateNoteRequest.serialize, - response_deserializer=grafeas.Note.deserialize, - ) - return self._stubs['create_note'] - - @property - def batch_create_notes(self) -> Callable[ - [grafeas.BatchCreateNotesRequest], - Awaitable[grafeas.BatchCreateNotesResponse]]: - r"""Return a callable for the batch create notes method over gRPC. - - Creates new notes in batch. - - Returns: - Callable[[~.BatchCreateNotesRequest], - Awaitable[~.BatchCreateNotesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_create_notes' not in self._stubs: - self._stubs['batch_create_notes'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/BatchCreateNotes', - request_serializer=grafeas.BatchCreateNotesRequest.serialize, - response_deserializer=grafeas.BatchCreateNotesResponse.deserialize, - ) - return self._stubs['batch_create_notes'] - - @property - def update_note(self) -> Callable[ - [grafeas.UpdateNoteRequest], - Awaitable[grafeas.Note]]: - r"""Return a callable for the update note method over gRPC. - - Updates the specified note. - - Returns: - Callable[[~.UpdateNoteRequest], - Awaitable[~.Note]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_note' not in self._stubs: - self._stubs['update_note'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/UpdateNote', - request_serializer=grafeas.UpdateNoteRequest.serialize, - response_deserializer=grafeas.Note.deserialize, - ) - return self._stubs['update_note'] - - @property - def list_note_occurrences(self) -> Callable[ - [grafeas.ListNoteOccurrencesRequest], - Awaitable[grafeas.ListNoteOccurrencesResponse]]: - r"""Return a callable for the list note occurrences method over gRPC. - - Lists occurrences referencing the specified note. - Provider projects can use this method to get all - occurrences across consumer projects referencing the - specified note. - - Returns: - Callable[[~.ListNoteOccurrencesRequest], - Awaitable[~.ListNoteOccurrencesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-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_note_occurrences' not in self._stubs: - self._stubs['list_note_occurrences'] = self.grpc_channel.unary_unary( - '/grafeas.v1.Grafeas/ListNoteOccurrences', - request_serializer=grafeas.ListNoteOccurrencesRequest.serialize, - response_deserializer=grafeas.ListNoteOccurrencesResponse.deserialize, - ) - return self._stubs['list_note_occurrences'] - - def _prep_wrapped_messages(self, client_info): - """ Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.get_occurrence: self._wrap_method( - self.get_occurrence, - default_retry=retries.AsyncRetry( - initial=0.1, - maximum=60.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.list_occurrences: self._wrap_method( - self.list_occurrences, - default_retry=retries.AsyncRetry( - initial=0.1, - maximum=60.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.delete_occurrence: self._wrap_method( - self.delete_occurrence, - default_retry=retries.AsyncRetry( - initial=0.1, - maximum=60.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.create_occurrence: self._wrap_method( - self.create_occurrence, - default_timeout=30.0, - client_info=client_info, - ), - self.batch_create_occurrences: self._wrap_method( - self.batch_create_occurrences, - default_timeout=30.0, - client_info=client_info, - ), - self.update_occurrence: self._wrap_method( - self.update_occurrence, - default_timeout=30.0, - client_info=client_info, - ), - self.get_occurrence_note: self._wrap_method( - self.get_occurrence_note, - default_retry=retries.AsyncRetry( - initial=0.1, - maximum=60.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.get_note: self._wrap_method( - self.get_note, - default_retry=retries.AsyncRetry( - initial=0.1, - maximum=60.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.list_notes: self._wrap_method( - self.list_notes, - default_retry=retries.AsyncRetry( - initial=0.1, - maximum=60.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.delete_note: self._wrap_method( - self.delete_note, - default_retry=retries.AsyncRetry( - initial=0.1, - maximum=60.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.create_note: self._wrap_method( - self.create_note, - default_timeout=30.0, - client_info=client_info, - ), - self.batch_create_notes: self._wrap_method( - self.batch_create_notes, - default_timeout=30.0, - client_info=client_info, - ), - self.update_note: self._wrap_method( - self.update_note, - default_timeout=30.0, - client_info=client_info, - ), - self.list_note_occurrences: self._wrap_method( - self.list_note_occurrences, - default_retry=retries.AsyncRetry( - initial=0.1, - maximum=60.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, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self.grpc_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ( - 'GrafeasGrpcAsyncIOTransport', -) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest.py deleted file mode 100644 index a3a7d2a3724b..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest.py +++ /dev/null @@ -1,1629 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 -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 gapic_v1 - -from google.protobuf import json_format - -from requests import __version__ as requests_version -import dataclasses -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union -import warnings - - -from google.protobuf import empty_pb2 # type: ignore -from grafeas.grafeas_v1.types import grafeas - - -from .rest_base import _BaseGrafeasRestTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, - grpc_version=None, - rest_version=f"requests@{requests_version}", -) - - -class GrafeasRestInterceptor: - """Interceptor for Grafeas. - - 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 GrafeasRestTransport. - - .. code-block:: python - class MyCustomGrafeasInterceptor(GrafeasRestInterceptor): - def pre_batch_create_notes(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_batch_create_notes(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_batch_create_occurrences(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_batch_create_occurrences(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_create_note(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_create_note(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_create_occurrence(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_create_occurrence(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_delete_note(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def pre_delete_occurrence(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def pre_get_note(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_get_note(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_get_occurrence(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_get_occurrence(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_get_occurrence_note(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_get_occurrence_note(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_list_note_occurrences(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_list_note_occurrences(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_list_notes(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_list_notes(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_list_occurrences(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_list_occurrences(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_update_note(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_update_note(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_update_occurrence(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_update_occurrence(self, response): - logging.log(f"Received response: {response}") - return response - - transport = GrafeasRestTransport(interceptor=MyCustomGrafeasInterceptor()) - client = GrafeasClient(transport=transport) - - - """ - def pre_batch_create_notes(self, request: grafeas.BatchCreateNotesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.BatchCreateNotesRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for batch_create_notes - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def post_batch_create_notes(self, response: grafeas.BatchCreateNotesResponse) -> grafeas.BatchCreateNotesResponse: - """Post-rpc interceptor for batch_create_notes - - Override in a subclass to manipulate the response - after it is returned by the Grafeas server but before - it is returned to user code. - """ - return response - - def pre_batch_create_occurrences(self, request: grafeas.BatchCreateOccurrencesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.BatchCreateOccurrencesRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for batch_create_occurrences - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def post_batch_create_occurrences(self, response: grafeas.BatchCreateOccurrencesResponse) -> grafeas.BatchCreateOccurrencesResponse: - """Post-rpc interceptor for batch_create_occurrences - - Override in a subclass to manipulate the response - after it is returned by the Grafeas server but before - it is returned to user code. - """ - return response - - def pre_create_note(self, request: grafeas.CreateNoteRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.CreateNoteRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for create_note - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def post_create_note(self, response: grafeas.Note) -> grafeas.Note: - """Post-rpc interceptor for create_note - - Override in a subclass to manipulate the response - after it is returned by the Grafeas server but before - it is returned to user code. - """ - return response - - def pre_create_occurrence(self, request: grafeas.CreateOccurrenceRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.CreateOccurrenceRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for create_occurrence - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def post_create_occurrence(self, response: grafeas.Occurrence) -> grafeas.Occurrence: - """Post-rpc interceptor for create_occurrence - - Override in a subclass to manipulate the response - after it is returned by the Grafeas server but before - it is returned to user code. - """ - return response - - def pre_delete_note(self, request: grafeas.DeleteNoteRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.DeleteNoteRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for delete_note - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def pre_delete_occurrence(self, request: grafeas.DeleteOccurrenceRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.DeleteOccurrenceRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for delete_occurrence - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def pre_get_note(self, request: grafeas.GetNoteRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.GetNoteRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for get_note - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def post_get_note(self, response: grafeas.Note) -> grafeas.Note: - """Post-rpc interceptor for get_note - - Override in a subclass to manipulate the response - after it is returned by the Grafeas server but before - it is returned to user code. - """ - return response - - def pre_get_occurrence(self, request: grafeas.GetOccurrenceRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.GetOccurrenceRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for get_occurrence - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def post_get_occurrence(self, response: grafeas.Occurrence) -> grafeas.Occurrence: - """Post-rpc interceptor for get_occurrence - - Override in a subclass to manipulate the response - after it is returned by the Grafeas server but before - it is returned to user code. - """ - return response - - def pre_get_occurrence_note(self, request: grafeas.GetOccurrenceNoteRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.GetOccurrenceNoteRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for get_occurrence_note - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def post_get_occurrence_note(self, response: grafeas.Note) -> grafeas.Note: - """Post-rpc interceptor for get_occurrence_note - - Override in a subclass to manipulate the response - after it is returned by the Grafeas server but before - it is returned to user code. - """ - return response - - def pre_list_note_occurrences(self, request: grafeas.ListNoteOccurrencesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.ListNoteOccurrencesRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for list_note_occurrences - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def post_list_note_occurrences(self, response: grafeas.ListNoteOccurrencesResponse) -> grafeas.ListNoteOccurrencesResponse: - """Post-rpc interceptor for list_note_occurrences - - Override in a subclass to manipulate the response - after it is returned by the Grafeas server but before - it is returned to user code. - """ - return response - - def pre_list_notes(self, request: grafeas.ListNotesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.ListNotesRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for list_notes - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def post_list_notes(self, response: grafeas.ListNotesResponse) -> grafeas.ListNotesResponse: - """Post-rpc interceptor for list_notes - - Override in a subclass to manipulate the response - after it is returned by the Grafeas server but before - it is returned to user code. - """ - return response - - def pre_list_occurrences(self, request: grafeas.ListOccurrencesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.ListOccurrencesRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for list_occurrences - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def post_list_occurrences(self, response: grafeas.ListOccurrencesResponse) -> grafeas.ListOccurrencesResponse: - """Post-rpc interceptor for list_occurrences - - Override in a subclass to manipulate the response - after it is returned by the Grafeas server but before - it is returned to user code. - """ - return response - - def pre_update_note(self, request: grafeas.UpdateNoteRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.UpdateNoteRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for update_note - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def post_update_note(self, response: grafeas.Note) -> grafeas.Note: - """Post-rpc interceptor for update_note - - Override in a subclass to manipulate the response - after it is returned by the Grafeas server but before - it is returned to user code. - """ - return response - - def pre_update_occurrence(self, request: grafeas.UpdateOccurrenceRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[grafeas.UpdateOccurrenceRequest, Sequence[Tuple[str, str]]]: - """Pre-rpc interceptor for update_occurrence - - Override in a subclass to manipulate the request or metadata - before they are sent to the Grafeas server. - """ - return request, metadata - - def post_update_occurrence(self, response: grafeas.Occurrence) -> grafeas.Occurrence: - """Post-rpc interceptor for update_occurrence - - Override in a subclass to manipulate the response - after it is returned by the Grafeas server but before - it is returned to user code. - """ - return response - - -@dataclasses.dataclass -class GrafeasRestStub: - _session: AuthorizedSession - _host: str - _interceptor: GrafeasRestInterceptor - - -class GrafeasRestTransport(_BaseGrafeasRestTransport): - """REST backend synchronous transport for Grafeas. - - `Grafeas `__ API. - - Retrieves analysis results of Cloud components such as Docker - container images. - - Analysis results are stored as a series of occurrences. An - ``Occurrence`` contains information about a specific analysis - instance on a resource. An occurrence refers to a ``Note``. A note - contains details describing the analysis and is generally stored in - a separate project, called a ``Provider``. Multiple occurrences can - refer to the same note. - - For example, an SSL vulnerability could affect multiple images. In - this case, there would be one note for the vulnerability and an - occurrence for each image with the vulnerability referring to that - note. - - 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 = 'containeranalysis.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[GrafeasRestInterceptor] = None, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'containeranalysis.googleapis.com'). - 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 - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - url_scheme=url_scheme, - 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 GrafeasRestInterceptor() - self._prep_wrapped_messages(client_info) - - class _BatchCreateNotes(_BaseGrafeasRestTransport._BaseBatchCreateNotes, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.BatchCreateNotes") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, - ) - return response - - def __call__(self, - request: grafeas.BatchCreateNotesRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> grafeas.BatchCreateNotesResponse: - r"""Call the batch create notes method over HTTP. - - Args: - request (~.grafeas.BatchCreateNotesRequest): - The request object. Request to create notes in batch. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.grafeas.BatchCreateNotesResponse: - Response for creating notes in batch. - """ - - http_options = _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_http_options() - request, metadata = self._interceptor.pre_batch_create_notes(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_transcoded_request(http_options, request) - - body = _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_request_body_json(transcoded_request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseBatchCreateNotes._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._BatchCreateNotes._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = grafeas.BatchCreateNotesResponse() - pb_resp = grafeas.BatchCreateNotesResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_batch_create_notes(resp) - return resp - - class _BatchCreateOccurrences(_BaseGrafeasRestTransport._BaseBatchCreateOccurrences, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.BatchCreateOccurrences") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, - ) - return response - - def __call__(self, - request: grafeas.BatchCreateOccurrencesRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> grafeas.BatchCreateOccurrencesResponse: - r"""Call the batch create occurrences method over HTTP. - - Args: - request (~.grafeas.BatchCreateOccurrencesRequest): - The request object. Request to create occurrences in - batch. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.grafeas.BatchCreateOccurrencesResponse: - Response for creating occurrences in - batch. - - """ - - http_options = _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_http_options() - request, metadata = self._interceptor.pre_batch_create_occurrences(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_transcoded_request(http_options, request) - - body = _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_request_body_json(transcoded_request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._BatchCreateOccurrences._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = grafeas.BatchCreateOccurrencesResponse() - pb_resp = grafeas.BatchCreateOccurrencesResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_batch_create_occurrences(resp) - return resp - - class _CreateNote(_BaseGrafeasRestTransport._BaseCreateNote, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.CreateNote") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, - ) - return response - - def __call__(self, - request: grafeas.CreateNoteRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> grafeas.Note: - r"""Call the create note method over HTTP. - - Args: - request (~.grafeas.CreateNoteRequest): - The request object. Request to create a new note. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.grafeas.Note: - A type of analysis that can be done - for a resource. - - """ - - http_options = _BaseGrafeasRestTransport._BaseCreateNote._get_http_options() - request, metadata = self._interceptor.pre_create_note(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseCreateNote._get_transcoded_request(http_options, request) - - body = _BaseGrafeasRestTransport._BaseCreateNote._get_request_body_json(transcoded_request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseCreateNote._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._CreateNote._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = grafeas.Note() - pb_resp = grafeas.Note.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_create_note(resp) - return resp - - class _CreateOccurrence(_BaseGrafeasRestTransport._BaseCreateOccurrence, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.CreateOccurrence") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, - ) - return response - - def __call__(self, - request: grafeas.CreateOccurrenceRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> grafeas.Occurrence: - r"""Call the create occurrence method over HTTP. - - Args: - request (~.grafeas.CreateOccurrenceRequest): - The request object. Request to create a new occurrence. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.grafeas.Occurrence: - An instance of an analysis type that - has been found on a resource. - - """ - - http_options = _BaseGrafeasRestTransport._BaseCreateOccurrence._get_http_options() - request, metadata = self._interceptor.pre_create_occurrence(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseCreateOccurrence._get_transcoded_request(http_options, request) - - body = _BaseGrafeasRestTransport._BaseCreateOccurrence._get_request_body_json(transcoded_request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseCreateOccurrence._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._CreateOccurrence._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = grafeas.Occurrence() - pb_resp = grafeas.Occurrence.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_create_occurrence(resp) - return resp - - class _DeleteNote(_BaseGrafeasRestTransport._BaseDeleteNote, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.DeleteNote") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__(self, - request: grafeas.DeleteNoteRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ): - r"""Call the delete note method over HTTP. - - Args: - request (~.grafeas.DeleteNoteRequest): - The request object. Request to delete a note. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be 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 = _BaseGrafeasRestTransport._BaseDeleteNote._get_http_options() - request, metadata = self._interceptor.pre_delete_note(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseDeleteNote._get_transcoded_request(http_options, request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseDeleteNote._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._DeleteNote._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) - - # 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 _DeleteOccurrence(_BaseGrafeasRestTransport._BaseDeleteOccurrence, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.DeleteOccurrence") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__(self, - request: grafeas.DeleteOccurrenceRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ): - r"""Call the delete occurrence method over HTTP. - - Args: - request (~.grafeas.DeleteOccurrenceRequest): - The request object. Request to delete an occurrence. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be 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 = _BaseGrafeasRestTransport._BaseDeleteOccurrence._get_http_options() - request, metadata = self._interceptor.pre_delete_occurrence(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseDeleteOccurrence._get_transcoded_request(http_options, request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseDeleteOccurrence._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._DeleteOccurrence._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) - - # 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 _GetNote(_BaseGrafeasRestTransport._BaseGetNote, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.GetNote") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__(self, - request: grafeas.GetNoteRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> grafeas.Note: - r"""Call the get note method over HTTP. - - Args: - request (~.grafeas.GetNoteRequest): - The request object. Request to get a note. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.grafeas.Note: - A type of analysis that can be done - for a resource. - - """ - - http_options = _BaseGrafeasRestTransport._BaseGetNote._get_http_options() - request, metadata = self._interceptor.pre_get_note(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseGetNote._get_transcoded_request(http_options, request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseGetNote._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._GetNote._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) - - # 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 = grafeas.Note() - pb_resp = grafeas.Note.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_note(resp) - return resp - - class _GetOccurrence(_BaseGrafeasRestTransport._BaseGetOccurrence, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.GetOccurrence") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__(self, - request: grafeas.GetOccurrenceRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> grafeas.Occurrence: - r"""Call the get occurrence method over HTTP. - - Args: - request (~.grafeas.GetOccurrenceRequest): - The request object. Request to get an occurrence. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.grafeas.Occurrence: - An instance of an analysis type that - has been found on a resource. - - """ - - http_options = _BaseGrafeasRestTransport._BaseGetOccurrence._get_http_options() - request, metadata = self._interceptor.pre_get_occurrence(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseGetOccurrence._get_transcoded_request(http_options, request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseGetOccurrence._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._GetOccurrence._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) - - # 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 = grafeas.Occurrence() - pb_resp = grafeas.Occurrence.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_occurrence(resp) - return resp - - class _GetOccurrenceNote(_BaseGrafeasRestTransport._BaseGetOccurrenceNote, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.GetOccurrenceNote") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__(self, - request: grafeas.GetOccurrenceNoteRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> grafeas.Note: - r"""Call the get occurrence note method over HTTP. - - Args: - request (~.grafeas.GetOccurrenceNoteRequest): - The request object. Request to get the note to which the - specified occurrence is attached. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.grafeas.Note: - A type of analysis that can be done - for a resource. - - """ - - http_options = _BaseGrafeasRestTransport._BaseGetOccurrenceNote._get_http_options() - request, metadata = self._interceptor.pre_get_occurrence_note(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseGetOccurrenceNote._get_transcoded_request(http_options, request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseGetOccurrenceNote._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._GetOccurrenceNote._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) - - # 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 = grafeas.Note() - pb_resp = grafeas.Note.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_occurrence_note(resp) - return resp - - class _ListNoteOccurrences(_BaseGrafeasRestTransport._BaseListNoteOccurrences, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.ListNoteOccurrences") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__(self, - request: grafeas.ListNoteOccurrencesRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> grafeas.ListNoteOccurrencesResponse: - r"""Call the list note occurrences method over HTTP. - - Args: - request (~.grafeas.ListNoteOccurrencesRequest): - The request object. Request to list occurrences for a - note. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.grafeas.ListNoteOccurrencesResponse: - Response for listing occurrences for - a note. - - """ - - http_options = _BaseGrafeasRestTransport._BaseListNoteOccurrences._get_http_options() - request, metadata = self._interceptor.pre_list_note_occurrences(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseListNoteOccurrences._get_transcoded_request(http_options, request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseListNoteOccurrences._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._ListNoteOccurrences._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) - - # 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 = grafeas.ListNoteOccurrencesResponse() - pb_resp = grafeas.ListNoteOccurrencesResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_note_occurrences(resp) - return resp - - class _ListNotes(_BaseGrafeasRestTransport._BaseListNotes, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.ListNotes") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__(self, - request: grafeas.ListNotesRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> grafeas.ListNotesResponse: - r"""Call the list notes method over HTTP. - - Args: - request (~.grafeas.ListNotesRequest): - The request object. Request to list notes. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.grafeas.ListNotesResponse: - Response for listing notes. - """ - - http_options = _BaseGrafeasRestTransport._BaseListNotes._get_http_options() - request, metadata = self._interceptor.pre_list_notes(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseListNotes._get_transcoded_request(http_options, request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseListNotes._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._ListNotes._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) - - # 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 = grafeas.ListNotesResponse() - pb_resp = grafeas.ListNotesResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_notes(resp) - return resp - - class _ListOccurrences(_BaseGrafeasRestTransport._BaseListOccurrences, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.ListOccurrences") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__(self, - request: grafeas.ListOccurrencesRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> grafeas.ListOccurrencesResponse: - r"""Call the list occurrences method over HTTP. - - Args: - request (~.grafeas.ListOccurrencesRequest): - The request object. Request to list occurrences. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.grafeas.ListOccurrencesResponse: - Response for listing occurrences. - """ - - http_options = _BaseGrafeasRestTransport._BaseListOccurrences._get_http_options() - request, metadata = self._interceptor.pre_list_occurrences(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseListOccurrences._get_transcoded_request(http_options, request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseListOccurrences._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._ListOccurrences._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request) - - # 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 = grafeas.ListOccurrencesResponse() - pb_resp = grafeas.ListOccurrencesResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_occurrences(resp) - return resp - - class _UpdateNote(_BaseGrafeasRestTransport._BaseUpdateNote, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.UpdateNote") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, - ) - return response - - def __call__(self, - request: grafeas.UpdateNoteRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> grafeas.Note: - r"""Call the update note method over HTTP. - - Args: - request (~.grafeas.UpdateNoteRequest): - The request object. Request to update a note. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.grafeas.Note: - A type of analysis that can be done - for a resource. - - """ - - http_options = _BaseGrafeasRestTransport._BaseUpdateNote._get_http_options() - request, metadata = self._interceptor.pre_update_note(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseUpdateNote._get_transcoded_request(http_options, request) - - body = _BaseGrafeasRestTransport._BaseUpdateNote._get_request_body_json(transcoded_request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseUpdateNote._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._UpdateNote._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = grafeas.Note() - pb_resp = grafeas.Note.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_update_note(resp) - return resp - - class _UpdateOccurrence(_BaseGrafeasRestTransport._BaseUpdateOccurrence, GrafeasRestStub): - def __hash__(self): - return hash("GrafeasRestTransport.UpdateOccurrence") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None): - - uri = transcoded_request['uri'] - method = transcoded_request['method'] - headers = dict(metadata) - headers['Content-Type'] = 'application/json' - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, - ) - return response - - def __call__(self, - request: grafeas.UpdateOccurrenceRequest, *, - retry: OptionalRetry=gapic_v1.method.DEFAULT, - timeout: Optional[float]=None, - metadata: Sequence[Tuple[str, str]]=(), - ) -> grafeas.Occurrence: - r"""Call the update occurrence method over HTTP. - - Args: - request (~.grafeas.UpdateOccurrenceRequest): - The request object. Request to update an occurrence. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, str]]): Strings which should be - sent along with the request as metadata. - - Returns: - ~.grafeas.Occurrence: - An instance of an analysis type that - has been found on a resource. - - """ - - http_options = _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_http_options() - request, metadata = self._interceptor.pre_update_occurrence(request, metadata) - transcoded_request = _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_transcoded_request(http_options, request) - - body = _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_request_body_json(transcoded_request) - - # Jsonify the query params - query_params = _BaseGrafeasRestTransport._BaseUpdateOccurrence._get_query_params_json(transcoded_request) - - # Send the request - response = GrafeasRestTransport._UpdateOccurrence._get_response(self._host, metadata, query_params, self._session, timeout, transcoded_request, 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 = grafeas.Occurrence() - pb_resp = grafeas.Occurrence.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_update_occurrence(resp) - return resp - - @property - def batch_create_notes(self) -> Callable[ - [grafeas.BatchCreateNotesRequest], - grafeas.BatchCreateNotesResponse]: - # 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._BatchCreateNotes(self._session, self._host, self._interceptor) # type: ignore - - @property - def batch_create_occurrences(self) -> Callable[ - [grafeas.BatchCreateOccurrencesRequest], - grafeas.BatchCreateOccurrencesResponse]: - # 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._BatchCreateOccurrences(self._session, self._host, self._interceptor) # type: ignore - - @property - def create_note(self) -> Callable[ - [grafeas.CreateNoteRequest], - grafeas.Note]: - # 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._CreateNote(self._session, self._host, self._interceptor) # type: ignore - - @property - def create_occurrence(self) -> Callable[ - [grafeas.CreateOccurrenceRequest], - grafeas.Occurrence]: - # 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._CreateOccurrence(self._session, self._host, self._interceptor) # type: ignore - - @property - def delete_note(self) -> Callable[ - [grafeas.DeleteNoteRequest], - 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._DeleteNote(self._session, self._host, self._interceptor) # type: ignore - - @property - def delete_occurrence(self) -> Callable[ - [grafeas.DeleteOccurrenceRequest], - 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._DeleteOccurrence(self._session, self._host, self._interceptor) # type: ignore - - @property - def get_note(self) -> Callable[ - [grafeas.GetNoteRequest], - grafeas.Note]: - # 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._GetNote(self._session, self._host, self._interceptor) # type: ignore - - @property - def get_occurrence(self) -> Callable[ - [grafeas.GetOccurrenceRequest], - grafeas.Occurrence]: - # 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._GetOccurrence(self._session, self._host, self._interceptor) # type: ignore - - @property - def get_occurrence_note(self) -> Callable[ - [grafeas.GetOccurrenceNoteRequest], - grafeas.Note]: - # 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._GetOccurrenceNote(self._session, self._host, self._interceptor) # type: ignore - - @property - def list_note_occurrences(self) -> Callable[ - [grafeas.ListNoteOccurrencesRequest], - grafeas.ListNoteOccurrencesResponse]: - # 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._ListNoteOccurrences(self._session, self._host, self._interceptor) # type: ignore - - @property - def list_notes(self) -> Callable[ - [grafeas.ListNotesRequest], - grafeas.ListNotesResponse]: - # 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._ListNotes(self._session, self._host, self._interceptor) # type: ignore - - @property - def list_occurrences(self) -> Callable[ - [grafeas.ListOccurrencesRequest], - grafeas.ListOccurrencesResponse]: - # 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._ListOccurrences(self._session, self._host, self._interceptor) # type: ignore - - @property - def update_note(self) -> Callable[ - [grafeas.UpdateNoteRequest], - grafeas.Note]: - # 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._UpdateNote(self._session, self._host, self._interceptor) # type: ignore - - @property - def update_occurrence(self) -> Callable[ - [grafeas.UpdateOccurrenceRequest], - grafeas.Occurrence]: - # 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._UpdateOccurrence(self._session, self._host, self._interceptor) # type: ignore - - @property - def kind(self) -> str: - return "rest" - - def close(self): - self._session.close() - - -__all__=( - 'GrafeasRestTransport', -) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest_base.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest_base.py deleted file mode 100644 index 64f998e72c3e..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/services/grafeas/transports/rest_base.py +++ /dev/null @@ -1,732 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 json # type: ignore -from google.api_core import path_template -from google.api_core import gapic_v1 - -from google.protobuf import json_format -from .base import GrafeasTransport, DEFAULT_CLIENT_INFO - -import re -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union - - -from google.protobuf import empty_pb2 # type: ignore -from grafeas.grafeas_v1.types import grafeas - - -class _BaseGrafeasRestTransport(GrafeasTransport): - """Base REST backend transport for Grafeas. - - Note: This class is not meant to be used directly. Use its sync and - async sub-classes instead. - - 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 = 'containeranalysis.googleapis.com', - credentials: Optional[Any] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - url_scheme: str = 'https', - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - Args: - host (Optional[str]): - The hostname to connect to (default: 'containeranalysis.googleapis.com'). - credentials (Optional[Any]): 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. - 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 - 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 - ) - - class _BaseBatchCreateNotes: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'post', - 'uri': '/v1/{parent=projects/*}/notes:batchCreate', - 'body': '*', - }, - { - 'method': 'post', - 'uri': '/v1/{parent=projects/*/locations/*}/notes:batchCreate', - 'body': '*', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.BatchCreateNotesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_request_body_json(transcoded_request): - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request['body'], - use_integers_for_enums=True - ) - return body - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseBatchCreateNotes._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseBatchCreateOccurrences: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'post', - 'uri': '/v1/{parent=projects/*}/occurrences:batchCreate', - 'body': '*', - }, - { - 'method': 'post', - 'uri': '/v1/{parent=projects/*/locations/*}/occurrences:batchCreate', - 'body': '*', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.BatchCreateOccurrencesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_request_body_json(transcoded_request): - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request['body'], - use_integers_for_enums=True - ) - return body - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseBatchCreateOccurrences._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseCreateNote: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "noteId" : "", } - - @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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'post', - 'uri': '/v1/{parent=projects/*}/notes', - 'body': 'note', - }, - { - 'method': 'post', - 'uri': '/v1/{parent=projects/*/locations/*}/notes', - 'body': 'note', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.CreateNoteRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_request_body_json(transcoded_request): - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request['body'], - use_integers_for_enums=True - ) - return body - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseCreateNote._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseCreateOccurrence: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'post', - 'uri': '/v1/{parent=projects/*}/occurrences', - 'body': 'occurrence', - }, - { - 'method': 'post', - 'uri': '/v1/{parent=projects/*/locations/*}/occurrences', - 'body': 'occurrence', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.CreateOccurrenceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_request_body_json(transcoded_request): - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request['body'], - use_integers_for_enums=True - ) - return body - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseCreateOccurrence._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseDeleteNote: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'delete', - 'uri': '/v1/{name=projects/*/notes/*}', - }, - { - 'method': 'delete', - 'uri': '/v1/{name=projects/*/locations/*/notes/*}', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.DeleteNoteRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseDeleteNote._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseDeleteOccurrence: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'delete', - 'uri': '/v1/{name=projects/*/occurrences/*}', - }, - { - 'method': 'delete', - 'uri': '/v1/{name=projects/*/locations/*/occurrences/*}', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.DeleteOccurrenceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseDeleteOccurrence._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseGetNote: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'get', - 'uri': '/v1/{name=projects/*/notes/*}', - }, - { - 'method': 'get', - 'uri': '/v1/{name=projects/*/locations/*/notes/*}', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.GetNoteRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseGetNote._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseGetOccurrence: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'get', - 'uri': '/v1/{name=projects/*/occurrences/*}', - }, - { - 'method': 'get', - 'uri': '/v1/{name=projects/*/locations/*/occurrences/*}', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.GetOccurrenceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseGetOccurrence._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseGetOccurrenceNote: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'get', - 'uri': '/v1/{name=projects/*/occurrences/*}/notes', - }, - { - 'method': 'get', - 'uri': '/v1/{name=projects/*/locations/*/occurrences/*}/notes', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.GetOccurrenceNoteRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseGetOccurrenceNote._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseListNoteOccurrences: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'get', - 'uri': '/v1/{name=projects/*/notes/*}/occurrences', - }, - { - 'method': 'get', - 'uri': '/v1/{name=projects/*/locations/*/notes/*}/occurrences', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.ListNoteOccurrencesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseListNoteOccurrences._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseListNotes: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'get', - 'uri': '/v1/{parent=projects/*}/notes', - }, - { - 'method': 'get', - 'uri': '/v1/{parent=projects/*/locations/*}/notes', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.ListNotesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseListNotes._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseListOccurrences: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'get', - 'uri': '/v1/{parent=projects/*}/occurrences', - }, - { - 'method': 'get', - 'uri': '/v1/{parent=projects/*/locations/*}/occurrences', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.ListOccurrencesRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseListOccurrences._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseUpdateNote: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'patch', - 'uri': '/v1/{name=projects/*/notes/*}', - 'body': 'note', - }, - { - 'method': 'patch', - 'uri': '/v1/{name=projects/*/locations/*/notes/*}', - 'body': 'note', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.UpdateNoteRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_request_body_json(transcoded_request): - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request['body'], - use_integers_for_enums=True - ) - return body - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseUpdateNote._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseUpdateOccurrence: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __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} - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [{ - 'method': 'patch', - 'uri': '/v1/{name=projects/*/occurrences/*}', - 'body': 'occurrence', - }, - { - 'method': 'patch', - 'uri': '/v1/{name=projects/*/locations/*/occurrences/*}', - 'body': 'occurrence', - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = grafeas.UpdateOccurrenceRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_request_body_json(transcoded_request): - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request['body'], - use_integers_for_enums=True - ) - return body - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads(json_format.MessageToJson( - transcoded_request['query_params'], - use_integers_for_enums=True, - )) - query_params.update(_BaseGrafeasRestTransport._BaseUpdateOccurrence._get_unset_required_fields(query_params)) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - -__all__=( - '_BaseGrafeasRestTransport', -) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/__init__.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/__init__.py deleted file mode 100644 index 76e667190447..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/__init__.py +++ /dev/null @@ -1,244 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .attestation import ( - AttestationNote, - AttestationOccurrence, - Jwt, -) -from .build import ( - BuildNote, - BuildOccurrence, -) -from .common import ( - Digest, - Envelope, - EnvelopeSignature, - FileLocation, - License, - RelatedUrl, - Signature, - NoteKind, -) -from .compliance import ( - ComplianceNote, - ComplianceOccurrence, - ComplianceVersion, - NonCompliantFile, -) -from .cvss import ( - CVSS, - CVSSv3, - CVSSVersion, -) -from .deployment import ( - DeploymentNote, - DeploymentOccurrence, -) -from .discovery import ( - DiscoveryNote, - DiscoveryOccurrence, -) -from .dsse_attestation import ( - DSSEAttestationNote, - DSSEAttestationOccurrence, -) -from .grafeas import ( - BatchCreateNotesRequest, - BatchCreateNotesResponse, - BatchCreateOccurrencesRequest, - BatchCreateOccurrencesResponse, - CreateNoteRequest, - CreateOccurrenceRequest, - DeleteNoteRequest, - DeleteOccurrenceRequest, - GetNoteRequest, - GetOccurrenceNoteRequest, - GetOccurrenceRequest, - ListNoteOccurrencesRequest, - ListNoteOccurrencesResponse, - ListNotesRequest, - ListNotesResponse, - ListOccurrencesRequest, - ListOccurrencesResponse, - Note, - Occurrence, - UpdateNoteRequest, - UpdateOccurrenceRequest, -) -from .image import ( - Fingerprint, - ImageNote, - ImageOccurrence, - Layer, -) -from .intoto_provenance import ( - BuilderConfig, - Completeness, - InTotoProvenance, - Metadata, - Recipe, -) -from .intoto_statement import ( - InTotoSlsaProvenanceV1, - InTotoStatement, - Subject, -) -from .package import ( - Distribution, - Location, - PackageNote, - PackageOccurrence, - Version, - Architecture, -) -from .provenance import ( - AliasContext, - Artifact, - BuildProvenance, - CloudRepoSourceContext, - Command, - FileHashes, - GerritSourceContext, - GitSourceContext, - Hash, - ProjectRepoId, - RepoId, - Source, - SourceContext, -) -from .sbom import ( - SbomReferenceIntotoPayload, - SbomReferenceIntotoPredicate, - SBOMReferenceNote, - SBOMReferenceOccurrence, -) -from .severity import ( - Severity, -) -from .slsa_provenance import ( - SlsaProvenance, -) -from .slsa_provenance_zero_two import ( - SlsaProvenanceZeroTwo, -) -from .upgrade import ( - UpgradeDistribution, - UpgradeNote, - UpgradeOccurrence, - WindowsUpdate, -) -from .vex import ( - VulnerabilityAssessmentNote, -) -from .vulnerability import ( - VulnerabilityNote, - VulnerabilityOccurrence, -) - -__all__ = ( - 'AttestationNote', - 'AttestationOccurrence', - 'Jwt', - 'BuildNote', - 'BuildOccurrence', - 'Digest', - 'Envelope', - 'EnvelopeSignature', - 'FileLocation', - 'License', - 'RelatedUrl', - 'Signature', - 'NoteKind', - 'ComplianceNote', - 'ComplianceOccurrence', - 'ComplianceVersion', - 'NonCompliantFile', - 'CVSS', - 'CVSSv3', - 'CVSSVersion', - 'DeploymentNote', - 'DeploymentOccurrence', - 'DiscoveryNote', - 'DiscoveryOccurrence', - 'DSSEAttestationNote', - 'DSSEAttestationOccurrence', - 'BatchCreateNotesRequest', - 'BatchCreateNotesResponse', - 'BatchCreateOccurrencesRequest', - 'BatchCreateOccurrencesResponse', - 'CreateNoteRequest', - 'CreateOccurrenceRequest', - 'DeleteNoteRequest', - 'DeleteOccurrenceRequest', - 'GetNoteRequest', - 'GetOccurrenceNoteRequest', - 'GetOccurrenceRequest', - 'ListNoteOccurrencesRequest', - 'ListNoteOccurrencesResponse', - 'ListNotesRequest', - 'ListNotesResponse', - 'ListOccurrencesRequest', - 'ListOccurrencesResponse', - 'Note', - 'Occurrence', - 'UpdateNoteRequest', - 'UpdateOccurrenceRequest', - 'Fingerprint', - 'ImageNote', - 'ImageOccurrence', - 'Layer', - 'BuilderConfig', - 'Completeness', - 'InTotoProvenance', - 'Metadata', - 'Recipe', - 'InTotoSlsaProvenanceV1', - 'InTotoStatement', - 'Subject', - 'Distribution', - 'Location', - 'PackageNote', - 'PackageOccurrence', - 'Version', - 'Architecture', - 'AliasContext', - 'Artifact', - 'BuildProvenance', - 'CloudRepoSourceContext', - 'Command', - 'FileHashes', - 'GerritSourceContext', - 'GitSourceContext', - 'Hash', - 'ProjectRepoId', - 'RepoId', - 'Source', - 'SourceContext', - 'SbomReferenceIntotoPayload', - 'SbomReferenceIntotoPredicate', - 'SBOMReferenceNote', - 'SBOMReferenceOccurrence', - 'Severity', - 'SlsaProvenance', - 'SlsaProvenanceZeroTwo', - 'UpgradeDistribution', - 'UpgradeNote', - 'UpgradeOccurrence', - 'WindowsUpdate', - 'VulnerabilityAssessmentNote', - 'VulnerabilityNote', - 'VulnerabilityOccurrence', -) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/attestation.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/attestation.py deleted file mode 100644 index b001a8ec82a7..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/attestation.py +++ /dev/null @@ -1,148 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import common - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'AttestationNote', - 'Jwt', - 'AttestationOccurrence', - }, -) - - -class AttestationNote(proto.Message): - r"""Note kind that represents a logical attestation "role" or - "authority". For example, an organization might have one - ``Authority`` for "QA" and one for "build". This note is intended to - act strictly as a grouping mechanism for the attached occurrences - (Attestations). This grouping mechanism also provides a security - boundary, since IAM ACLs gate the ability for a principle to attach - an occurrence to a given note. It also provides a single point of - lookup to find all attached attestation occurrences, even if they - don't all live in the same project. - - Attributes: - hint (grafeas.grafeas_v1.types.AttestationNote.Hint): - Hint hints at the purpose of the attestation - authority. - """ - - class Hint(proto.Message): - r"""This submessage provides human-readable hints about the - purpose of the authority. Because the name of a note acts as its - resource reference, it is important to disambiguate the - canonical name of the Note (which might be a UUID for security - purposes) from "readable" names more suitable for debug output. - Note that these hints should not be used to look up authorities - in security sensitive contexts, such as when looking up - attestations to verify. - - Attributes: - human_readable_name (str): - Required. The human readable name of this - attestation authority, for example "qa". - """ - - human_readable_name: str = proto.Field( - proto.STRING, - number=1, - ) - - hint: Hint = proto.Field( - proto.MESSAGE, - number=1, - message=Hint, - ) - - -class Jwt(proto.Message): - r""" - - Attributes: - compact_jwt (str): - The compact encoding of a JWS, which is - always three base64 encoded strings joined by - periods. For details, see: - - https://tools.ietf.org/html/rfc7515.html#section-3.1 - """ - - compact_jwt: str = proto.Field( - proto.STRING, - number=1, - ) - - -class AttestationOccurrence(proto.Message): - r"""Occurrence that represents a single "attestation". The - authenticity of an attestation can be verified using the - attached signature. If the verifier trusts the public key of the - signer, then verifying the signature is sufficient to establish - trust. In this circumstance, the authority to which this - attestation is attached is primarily useful for lookup (how to - find this attestation if you already know the authority and - artifact to be verified) and intent (for which authority this - attestation was intended to sign. - - Attributes: - serialized_payload (bytes): - Required. The serialized payload that is verified by one or - more ``signatures``. - signatures (MutableSequence[grafeas.grafeas_v1.types.Signature]): - One or more signatures over ``serialized_payload``. Verifier - implementations should consider this attestation message - verified if at least one ``signature`` verifies - ``serialized_payload``. See ``Signature`` in common.proto - for more details on signature structure and verification. - jwts (MutableSequence[grafeas.grafeas_v1.types.Jwt]): - One or more JWTs encoding a self-contained attestation. Each - JWT encodes the payload that it verifies within the JWT - itself. Verifier implementation SHOULD ignore the - ``serialized_payload`` field when verifying these JWTs. If - only JWTs are present on this AttestationOccurrence, then - the ``serialized_payload`` SHOULD be left empty. Each JWT - SHOULD encode a claim specific to the ``resource_uri`` of - this Occurrence, but this is not validated by Grafeas - metadata API implementations. The JWT itself is opaque to - Grafeas. - """ - - serialized_payload: bytes = proto.Field( - proto.BYTES, - number=1, - ) - signatures: MutableSequence[common.Signature] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message=common.Signature, - ) - jwts: MutableSequence['Jwt'] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message='Jwt', - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/build.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/build.py deleted file mode 100644 index 10eea8a73894..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/build.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import intoto_provenance as g_intoto_provenance -from grafeas.grafeas_v1.types import intoto_statement as g_intoto_statement -from grafeas.grafeas_v1.types import provenance as g_provenance - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'BuildNote', - 'BuildOccurrence', - }, -) - - -class BuildNote(proto.Message): - r"""Note holding the version of the provider's builder and the - signature of the provenance message in the build details - occurrence. - - Attributes: - builder_version (str): - Required. Immutable. Version of the builder - which produced this build. - """ - - builder_version: str = proto.Field( - proto.STRING, - number=1, - ) - - -class BuildOccurrence(proto.Message): - r"""Details of a build occurrence. - - Attributes: - provenance (grafeas.grafeas_v1.types.BuildProvenance): - The actual provenance for the build. - provenance_bytes (str): - Serialized JSON representation of the provenance, used in - generating the build signature in the corresponding build - note. After verifying the signature, ``provenance_bytes`` - can be unmarshalled and compared to the provenance to - confirm that it is unchanged. A base64-encoded string - representation of the provenance bytes is used for the - signature in order to interoperate with openssl which - expects this format for signature verification. - - The serialized form is captured both to avoid ambiguity in - how the provenance is marshalled to json as well to prevent - incompatibilities with future changes. - intoto_provenance (grafeas.grafeas_v1.types.InTotoProvenance): - Deprecated. See InTotoStatement for the - replacement. In-toto Provenance representation - as defined in spec. - intoto_statement (grafeas.grafeas_v1.types.InTotoStatement): - In-toto Statement representation as defined in spec. The - intoto_statement can contain any type of provenance. The - serialized payload of the statement can be stored and signed - in the Occurrence's envelope. - in_toto_slsa_provenance_v1 (grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1): - In-Toto Slsa Provenance V1 represents a slsa - provenance meeting the slsa spec, wrapped in an - in-toto statement. This allows for direct - jsonification of a to-spec in-toto slsa - statement with a to-spec slsa provenance. - """ - - provenance: g_provenance.BuildProvenance = proto.Field( - proto.MESSAGE, - number=1, - message=g_provenance.BuildProvenance, - ) - provenance_bytes: str = proto.Field( - proto.STRING, - number=2, - ) - intoto_provenance: g_intoto_provenance.InTotoProvenance = proto.Field( - proto.MESSAGE, - number=3, - message=g_intoto_provenance.InTotoProvenance, - ) - intoto_statement: g_intoto_statement.InTotoStatement = proto.Field( - proto.MESSAGE, - number=4, - message=g_intoto_statement.InTotoStatement, - ) - in_toto_slsa_provenance_v1: g_intoto_statement.InTotoSlsaProvenanceV1 = proto.Field( - proto.MESSAGE, - number=5, - message=g_intoto_statement.InTotoSlsaProvenanceV1, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/common.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/common.py deleted file mode 100644 index 047f564874ba..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/common.py +++ /dev/null @@ -1,295 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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='grafeas.v1', - manifest={ - 'NoteKind', - 'RelatedUrl', - 'Signature', - 'Envelope', - 'EnvelopeSignature', - 'FileLocation', - 'License', - 'Digest', - }, -) - - -class NoteKind(proto.Enum): - r"""Kind represents the kinds of notes supported. - - Values: - NOTE_KIND_UNSPECIFIED (0): - Default value. This value is unused. - VULNERABILITY (1): - The note and occurrence represent a package - vulnerability. - BUILD (2): - The note and occurrence assert build - provenance. - IMAGE (3): - This represents an image basis relationship. - PACKAGE (4): - This represents a package installed via a - package manager. - DEPLOYMENT (5): - The note and occurrence track deployment - events. - DISCOVERY (6): - The note and occurrence track the initial - discovery status of a resource. - ATTESTATION (7): - This represents a logical "role" that can - attest to artifacts. - UPGRADE (8): - This represents an available package upgrade. - COMPLIANCE (9): - This represents a Compliance Note - DSSE_ATTESTATION (10): - This represents a DSSE attestation Note - VULNERABILITY_ASSESSMENT (11): - This represents a Vulnerability Assessment. - SBOM_REFERENCE (12): - This represents an SBOM Reference. - """ - NOTE_KIND_UNSPECIFIED = 0 - VULNERABILITY = 1 - BUILD = 2 - IMAGE = 3 - PACKAGE = 4 - DEPLOYMENT = 5 - DISCOVERY = 6 - ATTESTATION = 7 - UPGRADE = 8 - COMPLIANCE = 9 - DSSE_ATTESTATION = 10 - VULNERABILITY_ASSESSMENT = 11 - SBOM_REFERENCE = 12 - - -class RelatedUrl(proto.Message): - r"""Metadata for any related URL information. - - Attributes: - url (str): - Specific URL associated with the resource. - label (str): - Label to describe usage of the URL. - """ - - url: str = proto.Field( - proto.STRING, - number=1, - ) - label: str = proto.Field( - proto.STRING, - number=2, - ) - - -class Signature(proto.Message): - r"""Verifiers (e.g. Kritis implementations) MUST verify signatures with - respect to the trust anchors defined in policy (e.g. a Kritis - policy). Typically this means that the verifier has been configured - with a map from ``public_key_id`` to public key material (and any - required parameters, e.g. signing algorithm). - - In particular, verification implementations MUST NOT treat the - signature ``public_key_id`` as anything more than a key lookup hint. - The ``public_key_id`` DOES NOT validate or authenticate a public - key; it only provides a mechanism for quickly selecting a public key - ALREADY CONFIGURED on the verifier through a trusted channel. - Verification implementations MUST reject signatures in any of the - following circumstances: - - - The ``public_key_id`` is not recognized by the verifier. - - The public key that ``public_key_id`` refers to does not verify - the signature with respect to the payload. - - The ``signature`` contents SHOULD NOT be "attached" (where the - payload is included with the serialized ``signature`` bytes). - Verifiers MUST ignore any "attached" payload and only verify - signatures with respect to explicitly provided payload (e.g. a - ``payload`` field on the proto message that holds this Signature, or - the canonical serialization of the proto message that holds this - signature). - - Attributes: - signature (bytes): - The content of the signature, an opaque - bytestring. The payload that this signature - verifies MUST be unambiguously provided with the - Signature during verification. A wrapper message - might provide the payload explicitly. - Alternatively, a message might have a canonical - serialization that can always be unambiguously - computed to derive the payload. - public_key_id (str): - The identifier for the public key that verifies this - signature. - - - The ``public_key_id`` is required. - - The ``public_key_id`` SHOULD be an RFC3986 conformant - URI. - - When possible, the ``public_key_id`` SHOULD be an - immutable reference, such as a cryptographic digest. - - Examples of valid ``public_key_id``\ s: - - OpenPGP V4 public key fingerprint: - - - "openpgp4fpr:74FAF3B861BDA0870C7B6DEF607E48D2A663AEEA" - See - https://www.iana.org/assignments/uri-schemes/prov/openpgp4fpr - for more details on this scheme. - - RFC6920 digest-named SubjectPublicKeyInfo (digest of the DER - serialization): - - - "ni:///sha-256;cD9o9Cq6LG3jD0iKXqEi_vdjJGecm_iXkbqVoScViaU" - - "nih:///sha-256;703f68f42aba2c6de30f488a5ea122fef76324679c9bf89791ba95a1271589a5". - """ - - signature: bytes = proto.Field( - proto.BYTES, - number=1, - ) - public_key_id: str = proto.Field( - proto.STRING, - number=2, - ) - - -class Envelope(proto.Message): - r"""MUST match - https://github.com/secure-systems-lab/dsse/blob/master/envelope.proto. - An authenticated message of arbitrary type. - - Attributes: - payload (bytes): - - payload_type (str): - - signatures (MutableSequence[grafeas.grafeas_v1.types.EnvelopeSignature]): - - """ - - payload: bytes = proto.Field( - proto.BYTES, - number=1, - ) - payload_type: str = proto.Field( - proto.STRING, - number=2, - ) - signatures: MutableSequence['EnvelopeSignature'] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message='EnvelopeSignature', - ) - - -class EnvelopeSignature(proto.Message): - r""" - - Attributes: - sig (bytes): - - keyid (str): - - """ - - sig: bytes = proto.Field( - proto.BYTES, - number=1, - ) - keyid: str = proto.Field( - proto.STRING, - number=2, - ) - - -class FileLocation(proto.Message): - r"""Indicates the location at which a package was found. - - Attributes: - file_path (str): - For jars that are contained inside .war - files, this filepath can indicate the path to - war file combined with the path to jar file. - """ - - file_path: str = proto.Field( - proto.STRING, - number=1, - ) - - -class License(proto.Message): - r"""License information. - - Attributes: - expression (str): - Often a single license can be used to - represent the licensing terms. Sometimes it is - necessary to include a choice of one or more - licenses or some combination of license - identifiers. - Examples: "LGPL-2.1-only OR MIT", "LGPL-2.1-only - AND MIT", "GPL-2.0-or-later WITH - Bison-exception-2.2". - comments (str): - Comments - """ - - expression: str = proto.Field( - proto.STRING, - number=1, - ) - comments: str = proto.Field( - proto.STRING, - number=2, - ) - - -class Digest(proto.Message): - r"""Digest information. - - Attributes: - algo (str): - ``SHA1``, ``SHA512`` etc. - digest_bytes (bytes): - Value of the digest. - """ - - algo: str = proto.Field( - proto.STRING, - number=1, - ) - digest_bytes: bytes = proto.Field( - proto.BYTES, - number=2, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/compliance.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/compliance.py deleted file mode 100644 index b770fe9748cc..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/compliance.py +++ /dev/null @@ -1,215 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import severity as g_severity - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'ComplianceNote', - 'ComplianceVersion', - 'ComplianceOccurrence', - 'NonCompliantFile', - }, -) - - -class ComplianceNote(proto.Message): - r""" - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - title (str): - The title that identifies this compliance - check. - description (str): - A description about this compliance check. - version (MutableSequence[grafeas.grafeas_v1.types.ComplianceVersion]): - The OS and config versions the benchmark - applies to. - rationale (str): - A rationale for the existence of this - compliance check. - remediation (str): - A description of remediation steps if the - compliance check fails. - cis_benchmark (grafeas.grafeas_v1.types.ComplianceNote.CisBenchmark): - - This field is a member of `oneof`_ ``compliance_type``. - scan_instructions (bytes): - Serialized scan instructions with a - predefined format. - impact (str): - - This field is a member of `oneof`_ ``potential_impact``. - """ - - class CisBenchmark(proto.Message): - r"""A compliance check that is a CIS benchmark. - - Attributes: - profile_level (int): - - severity (grafeas.grafeas_v1.types.Severity): - - """ - - profile_level: int = proto.Field( - proto.INT32, - number=1, - ) - severity: g_severity.Severity = proto.Field( - proto.ENUM, - number=2, - enum=g_severity.Severity, - ) - - title: str = proto.Field( - proto.STRING, - number=1, - ) - description: str = proto.Field( - proto.STRING, - number=2, - ) - version: MutableSequence['ComplianceVersion'] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message='ComplianceVersion', - ) - rationale: str = proto.Field( - proto.STRING, - number=4, - ) - remediation: str = proto.Field( - proto.STRING, - number=5, - ) - cis_benchmark: CisBenchmark = proto.Field( - proto.MESSAGE, - number=6, - oneof='compliance_type', - message=CisBenchmark, - ) - scan_instructions: bytes = proto.Field( - proto.BYTES, - number=7, - ) - impact: str = proto.Field( - proto.STRING, - number=8, - oneof='potential_impact', - ) - - -class ComplianceVersion(proto.Message): - r"""Describes the CIS benchmark version that is applicable to a - given OS and os version. - - Attributes: - cpe_uri (str): - The CPE URI - (https://cpe.mitre.org/specification/) this - benchmark is applicable to. - benchmark_document (str): - The name of the document that defines this - benchmark, e.g. "CIS Container-Optimized OS". - version (str): - The version of the benchmark. This is set to - the version of the OS-specific CIS document the - benchmark is defined in. - """ - - cpe_uri: str = proto.Field( - proto.STRING, - number=1, - ) - benchmark_document: str = proto.Field( - proto.STRING, - number=3, - ) - version: str = proto.Field( - proto.STRING, - number=2, - ) - - -class ComplianceOccurrence(proto.Message): - r"""An indication that the compliance checks in the associated - ComplianceNote were not satisfied for particular resources or a - specified reason. - - Attributes: - non_compliant_files (MutableSequence[grafeas.grafeas_v1.types.NonCompliantFile]): - - non_compliance_reason (str): - - version (grafeas.grafeas_v1.types.ComplianceVersion): - The OS and config version the benchmark was - run on. - """ - - non_compliant_files: MutableSequence['NonCompliantFile'] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message='NonCompliantFile', - ) - non_compliance_reason: str = proto.Field( - proto.STRING, - number=3, - ) - version: 'ComplianceVersion' = proto.Field( - proto.MESSAGE, - number=4, - message='ComplianceVersion', - ) - - -class NonCompliantFile(proto.Message): - r"""Details about files that caused a compliance check to fail. - - Attributes: - path (str): - Empty if ``display_command`` is set. - display_command (str): - Command to display the non-compliant files. - reason (str): - Explains why a file is non compliant for a - CIS check. - """ - - path: str = proto.Field( - proto.STRING, - number=1, - ) - display_command: str = proto.Field( - proto.STRING, - number=2, - ) - reason: str = proto.Field( - proto.STRING, - number=3, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/cvss.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/cvss.py deleted file mode 100644 index e0e252edac00..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/cvss.py +++ /dev/null @@ -1,464 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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='grafeas.v1', - manifest={ - 'CVSSVersion', - 'CVSSv3', - 'CVSS', - }, -) - - -class CVSSVersion(proto.Enum): - r"""CVSS Version. - - Values: - CVSS_VERSION_UNSPECIFIED (0): - No description available. - CVSS_VERSION_2 (1): - No description available. - CVSS_VERSION_3 (2): - No description available. - """ - CVSS_VERSION_UNSPECIFIED = 0 - CVSS_VERSION_2 = 1 - CVSS_VERSION_3 = 2 - - -class CVSSv3(proto.Message): - r"""Common Vulnerability Scoring System version 3. - For details, see - https://www.first.org/cvss/specification-document - - Attributes: - base_score (float): - The base score is a function of the base - metric scores. - exploitability_score (float): - - impact_score (float): - - attack_vector (grafeas.grafeas_v1.types.CVSSv3.AttackVector): - Base Metrics - Represents the intrinsic characteristics of a - vulnerability that are constant over time and - across user environments. - attack_complexity (grafeas.grafeas_v1.types.CVSSv3.AttackComplexity): - - privileges_required (grafeas.grafeas_v1.types.CVSSv3.PrivilegesRequired): - - user_interaction (grafeas.grafeas_v1.types.CVSSv3.UserInteraction): - - scope (grafeas.grafeas_v1.types.CVSSv3.Scope): - - confidentiality_impact (grafeas.grafeas_v1.types.CVSSv3.Impact): - - integrity_impact (grafeas.grafeas_v1.types.CVSSv3.Impact): - - availability_impact (grafeas.grafeas_v1.types.CVSSv3.Impact): - - """ - class AttackVector(proto.Enum): - r""" - - Values: - ATTACK_VECTOR_UNSPECIFIED (0): - No description available. - ATTACK_VECTOR_NETWORK (1): - No description available. - ATTACK_VECTOR_ADJACENT (2): - No description available. - ATTACK_VECTOR_LOCAL (3): - No description available. - ATTACK_VECTOR_PHYSICAL (4): - No description available. - """ - ATTACK_VECTOR_UNSPECIFIED = 0 - ATTACK_VECTOR_NETWORK = 1 - ATTACK_VECTOR_ADJACENT = 2 - ATTACK_VECTOR_LOCAL = 3 - ATTACK_VECTOR_PHYSICAL = 4 - - class AttackComplexity(proto.Enum): - r""" - - Values: - ATTACK_COMPLEXITY_UNSPECIFIED (0): - No description available. - ATTACK_COMPLEXITY_LOW (1): - No description available. - ATTACK_COMPLEXITY_HIGH (2): - No description available. - """ - ATTACK_COMPLEXITY_UNSPECIFIED = 0 - ATTACK_COMPLEXITY_LOW = 1 - ATTACK_COMPLEXITY_HIGH = 2 - - class PrivilegesRequired(proto.Enum): - r""" - - Values: - PRIVILEGES_REQUIRED_UNSPECIFIED (0): - No description available. - PRIVILEGES_REQUIRED_NONE (1): - No description available. - PRIVILEGES_REQUIRED_LOW (2): - No description available. - PRIVILEGES_REQUIRED_HIGH (3): - No description available. - """ - PRIVILEGES_REQUIRED_UNSPECIFIED = 0 - PRIVILEGES_REQUIRED_NONE = 1 - PRIVILEGES_REQUIRED_LOW = 2 - PRIVILEGES_REQUIRED_HIGH = 3 - - class UserInteraction(proto.Enum): - r""" - - Values: - USER_INTERACTION_UNSPECIFIED (0): - No description available. - USER_INTERACTION_NONE (1): - No description available. - USER_INTERACTION_REQUIRED (2): - No description available. - """ - USER_INTERACTION_UNSPECIFIED = 0 - USER_INTERACTION_NONE = 1 - USER_INTERACTION_REQUIRED = 2 - - class Scope(proto.Enum): - r""" - - Values: - SCOPE_UNSPECIFIED (0): - No description available. - SCOPE_UNCHANGED (1): - No description available. - SCOPE_CHANGED (2): - No description available. - """ - SCOPE_UNSPECIFIED = 0 - SCOPE_UNCHANGED = 1 - SCOPE_CHANGED = 2 - - class Impact(proto.Enum): - r""" - - Values: - IMPACT_UNSPECIFIED (0): - No description available. - IMPACT_HIGH (1): - No description available. - IMPACT_LOW (2): - No description available. - IMPACT_NONE (3): - No description available. - """ - IMPACT_UNSPECIFIED = 0 - IMPACT_HIGH = 1 - IMPACT_LOW = 2 - IMPACT_NONE = 3 - - base_score: float = proto.Field( - proto.FLOAT, - number=1, - ) - exploitability_score: float = proto.Field( - proto.FLOAT, - number=2, - ) - impact_score: float = proto.Field( - proto.FLOAT, - number=3, - ) - attack_vector: AttackVector = proto.Field( - proto.ENUM, - number=5, - enum=AttackVector, - ) - attack_complexity: AttackComplexity = proto.Field( - proto.ENUM, - number=6, - enum=AttackComplexity, - ) - privileges_required: PrivilegesRequired = proto.Field( - proto.ENUM, - number=7, - enum=PrivilegesRequired, - ) - user_interaction: UserInteraction = proto.Field( - proto.ENUM, - number=8, - enum=UserInteraction, - ) - scope: Scope = proto.Field( - proto.ENUM, - number=9, - enum=Scope, - ) - confidentiality_impact: Impact = proto.Field( - proto.ENUM, - number=10, - enum=Impact, - ) - integrity_impact: Impact = proto.Field( - proto.ENUM, - number=11, - enum=Impact, - ) - availability_impact: Impact = proto.Field( - proto.ENUM, - number=12, - enum=Impact, - ) - - -class CVSS(proto.Message): - r"""Common Vulnerability Scoring System. - For details, see - https://www.first.org/cvss/specification-document This is a - message we will try to use for storing various versions of CVSS - rather than making a separate proto for storing a specific - version. - - Attributes: - base_score (float): - The base score is a function of the base - metric scores. - exploitability_score (float): - - impact_score (float): - - attack_vector (grafeas.grafeas_v1.types.CVSS.AttackVector): - Base Metrics - Represents the intrinsic characteristics of a - vulnerability that are constant over time and - across user environments. - attack_complexity (grafeas.grafeas_v1.types.CVSS.AttackComplexity): - - authentication (grafeas.grafeas_v1.types.CVSS.Authentication): - - privileges_required (grafeas.grafeas_v1.types.CVSS.PrivilegesRequired): - - user_interaction (grafeas.grafeas_v1.types.CVSS.UserInteraction): - - scope (grafeas.grafeas_v1.types.CVSS.Scope): - - confidentiality_impact (grafeas.grafeas_v1.types.CVSS.Impact): - - integrity_impact (grafeas.grafeas_v1.types.CVSS.Impact): - - availability_impact (grafeas.grafeas_v1.types.CVSS.Impact): - - """ - class AttackVector(proto.Enum): - r""" - - Values: - ATTACK_VECTOR_UNSPECIFIED (0): - No description available. - ATTACK_VECTOR_NETWORK (1): - No description available. - ATTACK_VECTOR_ADJACENT (2): - No description available. - ATTACK_VECTOR_LOCAL (3): - No description available. - ATTACK_VECTOR_PHYSICAL (4): - No description available. - """ - ATTACK_VECTOR_UNSPECIFIED = 0 - ATTACK_VECTOR_NETWORK = 1 - ATTACK_VECTOR_ADJACENT = 2 - ATTACK_VECTOR_LOCAL = 3 - ATTACK_VECTOR_PHYSICAL = 4 - - class AttackComplexity(proto.Enum): - r""" - - Values: - ATTACK_COMPLEXITY_UNSPECIFIED (0): - No description available. - ATTACK_COMPLEXITY_LOW (1): - No description available. - ATTACK_COMPLEXITY_HIGH (2): - No description available. - ATTACK_COMPLEXITY_MEDIUM (3): - No description available. - """ - ATTACK_COMPLEXITY_UNSPECIFIED = 0 - ATTACK_COMPLEXITY_LOW = 1 - ATTACK_COMPLEXITY_HIGH = 2 - ATTACK_COMPLEXITY_MEDIUM = 3 - - class Authentication(proto.Enum): - r""" - - Values: - AUTHENTICATION_UNSPECIFIED (0): - No description available. - AUTHENTICATION_MULTIPLE (1): - No description available. - AUTHENTICATION_SINGLE (2): - No description available. - AUTHENTICATION_NONE (3): - No description available. - """ - AUTHENTICATION_UNSPECIFIED = 0 - AUTHENTICATION_MULTIPLE = 1 - AUTHENTICATION_SINGLE = 2 - AUTHENTICATION_NONE = 3 - - class PrivilegesRequired(proto.Enum): - r""" - - Values: - PRIVILEGES_REQUIRED_UNSPECIFIED (0): - No description available. - PRIVILEGES_REQUIRED_NONE (1): - No description available. - PRIVILEGES_REQUIRED_LOW (2): - No description available. - PRIVILEGES_REQUIRED_HIGH (3): - No description available. - """ - PRIVILEGES_REQUIRED_UNSPECIFIED = 0 - PRIVILEGES_REQUIRED_NONE = 1 - PRIVILEGES_REQUIRED_LOW = 2 - PRIVILEGES_REQUIRED_HIGH = 3 - - class UserInteraction(proto.Enum): - r""" - - Values: - USER_INTERACTION_UNSPECIFIED (0): - No description available. - USER_INTERACTION_NONE (1): - No description available. - USER_INTERACTION_REQUIRED (2): - No description available. - """ - USER_INTERACTION_UNSPECIFIED = 0 - USER_INTERACTION_NONE = 1 - USER_INTERACTION_REQUIRED = 2 - - class Scope(proto.Enum): - r""" - - Values: - SCOPE_UNSPECIFIED (0): - No description available. - SCOPE_UNCHANGED (1): - No description available. - SCOPE_CHANGED (2): - No description available. - """ - SCOPE_UNSPECIFIED = 0 - SCOPE_UNCHANGED = 1 - SCOPE_CHANGED = 2 - - class Impact(proto.Enum): - r""" - - Values: - IMPACT_UNSPECIFIED (0): - No description available. - IMPACT_HIGH (1): - No description available. - IMPACT_LOW (2): - No description available. - IMPACT_NONE (3): - No description available. - IMPACT_PARTIAL (4): - No description available. - IMPACT_COMPLETE (5): - No description available. - """ - IMPACT_UNSPECIFIED = 0 - IMPACT_HIGH = 1 - IMPACT_LOW = 2 - IMPACT_NONE = 3 - IMPACT_PARTIAL = 4 - IMPACT_COMPLETE = 5 - - base_score: float = proto.Field( - proto.FLOAT, - number=1, - ) - exploitability_score: float = proto.Field( - proto.FLOAT, - number=2, - ) - impact_score: float = proto.Field( - proto.FLOAT, - number=3, - ) - attack_vector: AttackVector = proto.Field( - proto.ENUM, - number=4, - enum=AttackVector, - ) - attack_complexity: AttackComplexity = proto.Field( - proto.ENUM, - number=5, - enum=AttackComplexity, - ) - authentication: Authentication = proto.Field( - proto.ENUM, - number=6, - enum=Authentication, - ) - privileges_required: PrivilegesRequired = proto.Field( - proto.ENUM, - number=7, - enum=PrivilegesRequired, - ) - user_interaction: UserInteraction = proto.Field( - proto.ENUM, - number=8, - enum=UserInteraction, - ) - scope: Scope = proto.Field( - proto.ENUM, - number=9, - enum=Scope, - ) - confidentiality_impact: Impact = proto.Field( - proto.ENUM, - number=10, - enum=Impact, - ) - integrity_impact: Impact = proto.Field( - proto.ENUM, - number=11, - enum=Impact, - ) - availability_impact: Impact = proto.Field( - proto.ENUM, - number=12, - enum=Impact, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/deployment.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/deployment.py deleted file mode 100644 index d22e451c7744..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/deployment.py +++ /dev/null @@ -1,125 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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='grafeas.v1', - manifest={ - 'DeploymentNote', - 'DeploymentOccurrence', - }, -) - - -class DeploymentNote(proto.Message): - r"""An artifact that can be deployed in some runtime. - - Attributes: - resource_uri (MutableSequence[str]): - Required. Resource URI for the artifact being - deployed. - """ - - resource_uri: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=1, - ) - - -class DeploymentOccurrence(proto.Message): - r"""The period during which some deployable was active in a - runtime. - - Attributes: - user_email (str): - Identity of the user that triggered this - deployment. - deploy_time (google.protobuf.timestamp_pb2.Timestamp): - Required. Beginning of the lifetime of this - deployment. - undeploy_time (google.protobuf.timestamp_pb2.Timestamp): - End of the lifetime of this deployment. - config (str): - Configuration used to create this deployment. - address (str): - Address of the runtime element hosting this - deployment. - resource_uri (MutableSequence[str]): - Output only. Resource URI for the artifact - being deployed taken from the deployable field - with the same name. - platform (grafeas.grafeas_v1.types.DeploymentOccurrence.Platform): - Platform hosting this deployment. - """ - class Platform(proto.Enum): - r"""Types of platforms. - - Values: - PLATFORM_UNSPECIFIED (0): - Unknown. - GKE (1): - Google Container Engine. - FLEX (2): - Google App Engine: Flexible Environment. - CUSTOM (3): - Custom user-defined platform. - """ - PLATFORM_UNSPECIFIED = 0 - GKE = 1 - FLEX = 2 - CUSTOM = 3 - - user_email: str = proto.Field( - proto.STRING, - number=1, - ) - deploy_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=2, - message=timestamp_pb2.Timestamp, - ) - undeploy_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=3, - message=timestamp_pb2.Timestamp, - ) - config: str = proto.Field( - proto.STRING, - number=4, - ) - address: str = proto.Field( - proto.STRING, - number=5, - ) - resource_uri: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=6, - ) - platform: Platform = proto.Field( - proto.ENUM, - number=7, - enum=Platform, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/discovery.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/discovery.py deleted file mode 100644 index 627ab994ae06..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/discovery.py +++ /dev/null @@ -1,281 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 -from grafeas.grafeas_v1.types import common - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'DiscoveryNote', - 'DiscoveryOccurrence', - }, -) - - -class DiscoveryNote(proto.Message): - r"""A note that indicates a type of analysis a provider would perform. - This note exists in a provider's project. A ``Discovery`` occurrence - is created in a consumer's project at the start of analysis. - - Attributes: - analysis_kind (grafeas.grafeas_v1.types.NoteKind): - Required. Immutable. The kind of analysis - that is handled by this discovery. - """ - - analysis_kind: common.NoteKind = proto.Field( - proto.ENUM, - number=1, - enum=common.NoteKind, - ) - - -class DiscoveryOccurrence(proto.Message): - r"""Provides information about the analysis status of a - discovered resource. - - Attributes: - continuous_analysis (grafeas.grafeas_v1.types.DiscoveryOccurrence.ContinuousAnalysis): - Whether the resource is continuously - analyzed. - analysis_status (grafeas.grafeas_v1.types.DiscoveryOccurrence.AnalysisStatus): - The status of discovery for the resource. - analysis_completed (grafeas.grafeas_v1.types.DiscoveryOccurrence.AnalysisCompleted): - - analysis_error (MutableSequence[google.rpc.status_pb2.Status]): - Indicates any errors encountered during - analysis of a resource. There could be 0 or more - of these errors. - analysis_status_error (google.rpc.status_pb2.Status): - When an error is encountered this will - contain a LocalizedMessage under details to show - to the user. The LocalizedMessage is output only - and populated by the API. - cpe (str): - The CPE of the resource being scanned. - last_scan_time (google.protobuf.timestamp_pb2.Timestamp): - The last time this resource was scanned. - archive_time (google.protobuf.timestamp_pb2.Timestamp): - The time occurrences related to this - discovery occurrence were archived. - sbom_status (grafeas.grafeas_v1.types.DiscoveryOccurrence.SBOMStatus): - The status of an SBOM generation. - vulnerability_attestation (grafeas.grafeas_v1.types.DiscoveryOccurrence.VulnerabilityAttestation): - The status of an vulnerability attestation - generation. - """ - class ContinuousAnalysis(proto.Enum): - r"""Whether the resource is continuously analyzed. - - Values: - CONTINUOUS_ANALYSIS_UNSPECIFIED (0): - Unknown. - ACTIVE (1): - The resource is continuously analyzed. - INACTIVE (2): - The resource is ignored for continuous - analysis. - """ - CONTINUOUS_ANALYSIS_UNSPECIFIED = 0 - ACTIVE = 1 - INACTIVE = 2 - - class AnalysisStatus(proto.Enum): - r"""Analysis status for a resource. Currently for initial - analysis only (not updated in continuous analysis). - - Values: - ANALYSIS_STATUS_UNSPECIFIED (0): - Unknown. - PENDING (1): - Resource is known but no action has been - taken yet. - SCANNING (2): - Resource is being analyzed. - FINISHED_SUCCESS (3): - Analysis has finished successfully. - COMPLETE (3): - Analysis has completed. - FINISHED_FAILED (4): - Analysis has finished unsuccessfully, the - analysis itself is in a bad state. - FINISHED_UNSUPPORTED (5): - The resource is known not to be supported. - """ - _pb_options = {'allow_alias': True} - ANALYSIS_STATUS_UNSPECIFIED = 0 - PENDING = 1 - SCANNING = 2 - FINISHED_SUCCESS = 3 - COMPLETE = 3 - FINISHED_FAILED = 4 - FINISHED_UNSUPPORTED = 5 - - class AnalysisCompleted(proto.Message): - r"""Indicates which analysis completed successfully. Multiple - types of analysis can be performed on a single resource. - - Attributes: - analysis_type (MutableSequence[str]): - - """ - - analysis_type: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=1, - ) - - class SBOMStatus(proto.Message): - r"""The status of an SBOM generation. - - Attributes: - sbom_state (grafeas.grafeas_v1.types.DiscoveryOccurrence.SBOMStatus.SBOMState): - The progress of the SBOM generation. - error (str): - If there was an error generating an SBOM, - this will indicate what that error was. - """ - class SBOMState(proto.Enum): - r"""An enum indicating the progress of the SBOM generation. - - Values: - SBOM_STATE_UNSPECIFIED (0): - Default unknown state. - PENDING (1): - SBOM scanning is pending. - COMPLETE (2): - SBOM scanning has completed. - """ - SBOM_STATE_UNSPECIFIED = 0 - PENDING = 1 - COMPLETE = 2 - - sbom_state: 'DiscoveryOccurrence.SBOMStatus.SBOMState' = proto.Field( - proto.ENUM, - number=1, - enum='DiscoveryOccurrence.SBOMStatus.SBOMState', - ) - error: str = proto.Field( - proto.STRING, - number=2, - ) - - class VulnerabilityAttestation(proto.Message): - r"""The status of an vulnerability attestation generation. - - Attributes: - last_attempt_time (google.protobuf.timestamp_pb2.Timestamp): - The last time we attempted to generate an - attestation. - state (grafeas.grafeas_v1.types.DiscoveryOccurrence.VulnerabilityAttestation.VulnerabilityAttestationState): - The success/failure state of the latest - attestation attempt. - error (str): - If failure, the error reason for why the - attestation generation failed. - """ - class VulnerabilityAttestationState(proto.Enum): - r"""An enum indicating the state of the attestation generation. - - Values: - VULNERABILITY_ATTESTATION_STATE_UNSPECIFIED (0): - Default unknown state. - SUCCESS (1): - Attestation was successfully generated and - stored. - FAILURE (2): - Attestation was unsuccessfully generated and - stored. - """ - VULNERABILITY_ATTESTATION_STATE_UNSPECIFIED = 0 - SUCCESS = 1 - FAILURE = 2 - - last_attempt_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=1, - message=timestamp_pb2.Timestamp, - ) - state: 'DiscoveryOccurrence.VulnerabilityAttestation.VulnerabilityAttestationState' = proto.Field( - proto.ENUM, - number=2, - enum='DiscoveryOccurrence.VulnerabilityAttestation.VulnerabilityAttestationState', - ) - error: str = proto.Field( - proto.STRING, - number=3, - ) - - continuous_analysis: ContinuousAnalysis = proto.Field( - proto.ENUM, - number=1, - enum=ContinuousAnalysis, - ) - analysis_status: AnalysisStatus = proto.Field( - proto.ENUM, - number=2, - enum=AnalysisStatus, - ) - analysis_completed: AnalysisCompleted = proto.Field( - proto.MESSAGE, - number=7, - message=AnalysisCompleted, - ) - analysis_error: MutableSequence[status_pb2.Status] = proto.RepeatedField( - proto.MESSAGE, - number=8, - message=status_pb2.Status, - ) - analysis_status_error: status_pb2.Status = proto.Field( - proto.MESSAGE, - number=3, - message=status_pb2.Status, - ) - cpe: str = proto.Field( - proto.STRING, - number=4, - ) - last_scan_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=5, - message=timestamp_pb2.Timestamp, - ) - archive_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=6, - message=timestamp_pb2.Timestamp, - ) - sbom_status: SBOMStatus = proto.Field( - proto.MESSAGE, - number=9, - message=SBOMStatus, - ) - vulnerability_attestation: VulnerabilityAttestation = proto.Field( - proto.MESSAGE, - number=10, - message=VulnerabilityAttestation, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/dsse_attestation.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/dsse_attestation.py deleted file mode 100644 index afc3dc412306..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/dsse_attestation.py +++ /dev/null @@ -1,102 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import common -from grafeas.grafeas_v1.types import intoto_statement - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'DSSEAttestationNote', - 'DSSEAttestationOccurrence', - }, -) - - -class DSSEAttestationNote(proto.Message): - r""" - - Attributes: - hint (grafeas.grafeas_v1.types.DSSEAttestationNote.DSSEHint): - DSSEHint hints at the purpose of the - attestation authority. - """ - - class DSSEHint(proto.Message): - r"""This submessage provides human-readable hints about the - purpose of the authority. Because the name of a note acts as its - resource reference, it is important to disambiguate the - canonical name of the Note (which might be a UUID for security - purposes) from "readable" names more suitable for debug output. - Note that these hints should not be used to look up authorities - in security sensitive contexts, such as when looking up - attestations to verify. - - Attributes: - human_readable_name (str): - Required. The human readable name of this - attestation authority, for example - "cloudbuild-prod". - """ - - human_readable_name: str = proto.Field( - proto.STRING, - number=1, - ) - - hint: DSSEHint = proto.Field( - proto.MESSAGE, - number=1, - message=DSSEHint, - ) - - -class DSSEAttestationOccurrence(proto.Message): - r"""Deprecated. Prefer to use a regular Occurrence, and populate - the Envelope at the top level of the Occurrence. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - envelope (grafeas.grafeas_v1.types.Envelope): - If doing something security critical, make - sure to verify the signatures in this metadata. - statement (grafeas.grafeas_v1.types.InTotoStatement): - - This field is a member of `oneof`_ ``decoded_payload``. - """ - - envelope: common.Envelope = proto.Field( - proto.MESSAGE, - number=1, - message=common.Envelope, - ) - statement: intoto_statement.InTotoStatement = proto.Field( - proto.MESSAGE, - number=2, - oneof='decoded_payload', - message=intoto_statement.InTotoStatement, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/grafeas.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/grafeas.py deleted file mode 100644 index b98b55887b0c..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/grafeas.py +++ /dev/null @@ -1,921 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 field_mask_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -from grafeas.grafeas_v1.types import attestation as g_attestation -from grafeas.grafeas_v1.types import build as g_build -from grafeas.grafeas_v1.types import common -from grafeas.grafeas_v1.types import compliance as g_compliance -from grafeas.grafeas_v1.types import deployment as g_deployment -from grafeas.grafeas_v1.types import discovery as g_discovery -from grafeas.grafeas_v1.types import dsse_attestation as g_dsse_attestation -from grafeas.grafeas_v1.types import image as g_image -from grafeas.grafeas_v1.types import package as g_package -from grafeas.grafeas_v1.types import sbom -from grafeas.grafeas_v1.types import upgrade as g_upgrade -from grafeas.grafeas_v1.types import vex -from grafeas.grafeas_v1.types import vulnerability as g_vulnerability - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'Occurrence', - 'Note', - 'GetOccurrenceRequest', - 'ListOccurrencesRequest', - 'ListOccurrencesResponse', - 'DeleteOccurrenceRequest', - 'CreateOccurrenceRequest', - 'UpdateOccurrenceRequest', - 'GetNoteRequest', - 'GetOccurrenceNoteRequest', - 'ListNotesRequest', - 'ListNotesResponse', - 'DeleteNoteRequest', - 'CreateNoteRequest', - 'UpdateNoteRequest', - 'ListNoteOccurrencesRequest', - 'ListNoteOccurrencesResponse', - 'BatchCreateNotesRequest', - 'BatchCreateNotesResponse', - 'BatchCreateOccurrencesRequest', - 'BatchCreateOccurrencesResponse', - }, -) - - -class Occurrence(proto.Message): - r"""An instance of an analysis type that has been found on a - resource. - - 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: - name (str): - Output only. The name of the occurrence in the form of - ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. - resource_uri (str): - Required. Immutable. A URI that represents the resource for - which the occurrence applies. For example, - ``https://gcr.io/project/image@sha256:123abc`` for a Docker - image. - note_name (str): - Required. Immutable. The analysis note associated with this - occurrence, in the form of - ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. This field can - be used as a filter in list requests. - kind (grafeas.grafeas_v1.types.NoteKind): - Output only. This explicitly denotes which of - the occurrence details are specified. This field - can be used as a filter in list requests. - remediation (str): - A description of actions that can be taken to - remedy the note. - create_time (google.protobuf.timestamp_pb2.Timestamp): - Output only. The time this occurrence was - created. - update_time (google.protobuf.timestamp_pb2.Timestamp): - Output only. The time this occurrence was - last updated. - vulnerability (grafeas.grafeas_v1.types.VulnerabilityOccurrence): - Describes a security vulnerability. - - This field is a member of `oneof`_ ``details``. - build (grafeas.grafeas_v1.types.BuildOccurrence): - Describes a verifiable build. - - This field is a member of `oneof`_ ``details``. - image (grafeas.grafeas_v1.types.ImageOccurrence): - Describes how this resource derives from the - basis in the associated note. - - This field is a member of `oneof`_ ``details``. - package (grafeas.grafeas_v1.types.PackageOccurrence): - Describes the installation of a package on - the linked resource. - - This field is a member of `oneof`_ ``details``. - deployment (grafeas.grafeas_v1.types.DeploymentOccurrence): - Describes the deployment of an artifact on a - runtime. - - This field is a member of `oneof`_ ``details``. - discovery (grafeas.grafeas_v1.types.DiscoveryOccurrence): - Describes when a resource was discovered. - - This field is a member of `oneof`_ ``details``. - attestation (grafeas.grafeas_v1.types.AttestationOccurrence): - Describes an attestation of an artifact. - - This field is a member of `oneof`_ ``details``. - upgrade (grafeas.grafeas_v1.types.UpgradeOccurrence): - Describes an available package upgrade on the - linked resource. - - This field is a member of `oneof`_ ``details``. - compliance (grafeas.grafeas_v1.types.ComplianceOccurrence): - Describes a compliance violation on a linked - resource. - - This field is a member of `oneof`_ ``details``. - dsse_attestation (grafeas.grafeas_v1.types.DSSEAttestationOccurrence): - Describes an attestation of an artifact using - dsse. - - This field is a member of `oneof`_ ``details``. - sbom_reference (grafeas.grafeas_v1.types.SBOMReferenceOccurrence): - Describes a specific SBOM reference - occurrences. - - This field is a member of `oneof`_ ``details``. - envelope (grafeas.grafeas_v1.types.Envelope): - https://github.com/secure-systems-lab/dsse - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - resource_uri: str = proto.Field( - proto.STRING, - number=2, - ) - note_name: str = proto.Field( - proto.STRING, - number=3, - ) - kind: common.NoteKind = proto.Field( - proto.ENUM, - number=4, - enum=common.NoteKind, - ) - remediation: str = proto.Field( - proto.STRING, - number=5, - ) - create_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=6, - message=timestamp_pb2.Timestamp, - ) - update_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=7, - message=timestamp_pb2.Timestamp, - ) - vulnerability: g_vulnerability.VulnerabilityOccurrence = proto.Field( - proto.MESSAGE, - number=8, - oneof='details', - message=g_vulnerability.VulnerabilityOccurrence, - ) - build: g_build.BuildOccurrence = proto.Field( - proto.MESSAGE, - number=9, - oneof='details', - message=g_build.BuildOccurrence, - ) - image: g_image.ImageOccurrence = proto.Field( - proto.MESSAGE, - number=10, - oneof='details', - message=g_image.ImageOccurrence, - ) - package: g_package.PackageOccurrence = proto.Field( - proto.MESSAGE, - number=11, - oneof='details', - message=g_package.PackageOccurrence, - ) - deployment: g_deployment.DeploymentOccurrence = proto.Field( - proto.MESSAGE, - number=12, - oneof='details', - message=g_deployment.DeploymentOccurrence, - ) - discovery: g_discovery.DiscoveryOccurrence = proto.Field( - proto.MESSAGE, - number=13, - oneof='details', - message=g_discovery.DiscoveryOccurrence, - ) - attestation: g_attestation.AttestationOccurrence = proto.Field( - proto.MESSAGE, - number=14, - oneof='details', - message=g_attestation.AttestationOccurrence, - ) - upgrade: g_upgrade.UpgradeOccurrence = proto.Field( - proto.MESSAGE, - number=15, - oneof='details', - message=g_upgrade.UpgradeOccurrence, - ) - compliance: g_compliance.ComplianceOccurrence = proto.Field( - proto.MESSAGE, - number=16, - oneof='details', - message=g_compliance.ComplianceOccurrence, - ) - dsse_attestation: g_dsse_attestation.DSSEAttestationOccurrence = proto.Field( - proto.MESSAGE, - number=17, - oneof='details', - message=g_dsse_attestation.DSSEAttestationOccurrence, - ) - sbom_reference: sbom.SBOMReferenceOccurrence = proto.Field( - proto.MESSAGE, - number=19, - oneof='details', - message=sbom.SBOMReferenceOccurrence, - ) - envelope: common.Envelope = proto.Field( - proto.MESSAGE, - number=18, - message=common.Envelope, - ) - - -class Note(proto.Message): - r"""A type of analysis that can be done for a resource. - - 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: - name (str): - Output only. The name of the note in the form of - ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. - short_description (str): - A one sentence description of this note. - long_description (str): - A detailed description of this note. - kind (grafeas.grafeas_v1.types.NoteKind): - Output only. The type of analysis. This field - can be used as a filter in list requests. - related_url (MutableSequence[grafeas.grafeas_v1.types.RelatedUrl]): - URLs associated with this note. - expiration_time (google.protobuf.timestamp_pb2.Timestamp): - Time of expiration for this note. Empty if - note does not expire. - create_time (google.protobuf.timestamp_pb2.Timestamp): - Output only. The time this note was created. - This field can be used as a filter in list - requests. - update_time (google.protobuf.timestamp_pb2.Timestamp): - Output only. The time this note was last - updated. This field can be used as a filter in - list requests. - related_note_names (MutableSequence[str]): - Other notes related to this note. - vulnerability (grafeas.grafeas_v1.types.VulnerabilityNote): - A note describing a package vulnerability. - - This field is a member of `oneof`_ ``type``. - build (grafeas.grafeas_v1.types.BuildNote): - A note describing build provenance for a - verifiable build. - - This field is a member of `oneof`_ ``type``. - image (grafeas.grafeas_v1.types.ImageNote): - A note describing a base image. - - This field is a member of `oneof`_ ``type``. - package (grafeas.grafeas_v1.types.PackageNote): - A note describing a package hosted by various - package managers. - - This field is a member of `oneof`_ ``type``. - deployment (grafeas.grafeas_v1.types.DeploymentNote): - A note describing something that can be - deployed. - - This field is a member of `oneof`_ ``type``. - discovery (grafeas.grafeas_v1.types.DiscoveryNote): - A note describing the initial analysis of a - resource. - - This field is a member of `oneof`_ ``type``. - attestation (grafeas.grafeas_v1.types.AttestationNote): - A note describing an attestation role. - - This field is a member of `oneof`_ ``type``. - upgrade (grafeas.grafeas_v1.types.UpgradeNote): - A note describing available package upgrades. - - This field is a member of `oneof`_ ``type``. - compliance (grafeas.grafeas_v1.types.ComplianceNote): - A note describing a compliance check. - - This field is a member of `oneof`_ ``type``. - dsse_attestation (grafeas.grafeas_v1.types.DSSEAttestationNote): - A note describing a dsse attestation note. - - This field is a member of `oneof`_ ``type``. - vulnerability_assessment (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote): - A note describing a vulnerability assessment. - - This field is a member of `oneof`_ ``type``. - sbom_reference (grafeas.grafeas_v1.types.SBOMReferenceNote): - A note describing an SBOM reference. - - This field is a member of `oneof`_ ``type``. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - short_description: str = proto.Field( - proto.STRING, - number=2, - ) - long_description: str = proto.Field( - proto.STRING, - number=3, - ) - kind: common.NoteKind = proto.Field( - proto.ENUM, - number=4, - enum=common.NoteKind, - ) - related_url: MutableSequence[common.RelatedUrl] = proto.RepeatedField( - proto.MESSAGE, - number=5, - message=common.RelatedUrl, - ) - expiration_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=6, - message=timestamp_pb2.Timestamp, - ) - create_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=7, - message=timestamp_pb2.Timestamp, - ) - update_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=8, - message=timestamp_pb2.Timestamp, - ) - related_note_names: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=9, - ) - vulnerability: g_vulnerability.VulnerabilityNote = proto.Field( - proto.MESSAGE, - number=10, - oneof='type', - message=g_vulnerability.VulnerabilityNote, - ) - build: g_build.BuildNote = proto.Field( - proto.MESSAGE, - number=11, - oneof='type', - message=g_build.BuildNote, - ) - image: g_image.ImageNote = proto.Field( - proto.MESSAGE, - number=12, - oneof='type', - message=g_image.ImageNote, - ) - package: g_package.PackageNote = proto.Field( - proto.MESSAGE, - number=13, - oneof='type', - message=g_package.PackageNote, - ) - deployment: g_deployment.DeploymentNote = proto.Field( - proto.MESSAGE, - number=14, - oneof='type', - message=g_deployment.DeploymentNote, - ) - discovery: g_discovery.DiscoveryNote = proto.Field( - proto.MESSAGE, - number=15, - oneof='type', - message=g_discovery.DiscoveryNote, - ) - attestation: g_attestation.AttestationNote = proto.Field( - proto.MESSAGE, - number=16, - oneof='type', - message=g_attestation.AttestationNote, - ) - upgrade: g_upgrade.UpgradeNote = proto.Field( - proto.MESSAGE, - number=17, - oneof='type', - message=g_upgrade.UpgradeNote, - ) - compliance: g_compliance.ComplianceNote = proto.Field( - proto.MESSAGE, - number=18, - oneof='type', - message=g_compliance.ComplianceNote, - ) - dsse_attestation: g_dsse_attestation.DSSEAttestationNote = proto.Field( - proto.MESSAGE, - number=19, - oneof='type', - message=g_dsse_attestation.DSSEAttestationNote, - ) - vulnerability_assessment: vex.VulnerabilityAssessmentNote = proto.Field( - proto.MESSAGE, - number=20, - oneof='type', - message=vex.VulnerabilityAssessmentNote, - ) - sbom_reference: sbom.SBOMReferenceNote = proto.Field( - proto.MESSAGE, - number=21, - oneof='type', - message=sbom.SBOMReferenceNote, - ) - - -class GetOccurrenceRequest(proto.Message): - r"""Request to get an occurrence. - - Attributes: - name (str): - The name of the occurrence in the form of - ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - - -class ListOccurrencesRequest(proto.Message): - r"""Request to list occurrences. - - Attributes: - parent (str): - The name of the project to list occurrences for in the form - of ``projects/[PROJECT_ID]``. - filter (str): - The filter expression. - page_size (int): - Number of occurrences to return in the list. - Must be positive. Max allowed page size is 1000. - If not specified, page size defaults to 20. - page_token (str): - Token to provide to skip to a particular spot - in the list. - """ - - parent: str = proto.Field( - proto.STRING, - number=1, - ) - filter: str = proto.Field( - proto.STRING, - number=2, - ) - page_size: int = proto.Field( - proto.INT32, - number=3, - ) - page_token: str = proto.Field( - proto.STRING, - number=4, - ) - - -class ListOccurrencesResponse(proto.Message): - r"""Response for listing occurrences. - - Attributes: - occurrences (MutableSequence[grafeas.grafeas_v1.types.Occurrence]): - The occurrences requested. - next_page_token (str): - The next pagination token in the list response. It should be - used as ``page_token`` for the following request. An empty - value means no more results. - """ - - @property - def raw_page(self): - return self - - occurrences: MutableSequence['Occurrence'] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message='Occurrence', - ) - next_page_token: str = proto.Field( - proto.STRING, - number=2, - ) - - -class DeleteOccurrenceRequest(proto.Message): - r"""Request to delete an occurrence. - - Attributes: - name (str): - The name of the occurrence in the form of - ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - - -class CreateOccurrenceRequest(proto.Message): - r"""Request to create a new occurrence. - - Attributes: - parent (str): - The name of the project in the form of - ``projects/[PROJECT_ID]``, under which the occurrence is to - be created. - occurrence (grafeas.grafeas_v1.types.Occurrence): - The occurrence to create. - """ - - parent: str = proto.Field( - proto.STRING, - number=1, - ) - occurrence: 'Occurrence' = proto.Field( - proto.MESSAGE, - number=2, - message='Occurrence', - ) - - -class UpdateOccurrenceRequest(proto.Message): - r"""Request to update an occurrence. - - Attributes: - name (str): - The name of the occurrence in the form of - ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. - occurrence (grafeas.grafeas_v1.types.Occurrence): - The updated occurrence. - update_mask (google.protobuf.field_mask_pb2.FieldMask): - The fields to update. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - occurrence: 'Occurrence' = proto.Field( - proto.MESSAGE, - number=2, - message='Occurrence', - ) - update_mask: field_mask_pb2.FieldMask = proto.Field( - proto.MESSAGE, - number=3, - message=field_mask_pb2.FieldMask, - ) - - -class GetNoteRequest(proto.Message): - r"""Request to get a note. - - Attributes: - name (str): - The name of the note in the form of - ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - - -class GetOccurrenceNoteRequest(proto.Message): - r"""Request to get the note to which the specified occurrence is - attached. - - Attributes: - name (str): - The name of the occurrence in the form of - ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - - -class ListNotesRequest(proto.Message): - r"""Request to list notes. - - Attributes: - parent (str): - The name of the project to list notes for in the form of - ``projects/[PROJECT_ID]``. - filter (str): - The filter expression. - page_size (int): - Number of notes to return in the list. Must - be positive. Max allowed page size is 1000. If - not specified, page size defaults to 20. - page_token (str): - Token to provide to skip to a particular spot - in the list. - """ - - parent: str = proto.Field( - proto.STRING, - number=1, - ) - filter: str = proto.Field( - proto.STRING, - number=2, - ) - page_size: int = proto.Field( - proto.INT32, - number=3, - ) - page_token: str = proto.Field( - proto.STRING, - number=4, - ) - - -class ListNotesResponse(proto.Message): - r"""Response for listing notes. - - Attributes: - notes (MutableSequence[grafeas.grafeas_v1.types.Note]): - The notes requested. - next_page_token (str): - The next pagination token in the list response. It should be - used as ``page_token`` for the following request. An empty - value means no more results. - """ - - @property - def raw_page(self): - return self - - notes: MutableSequence['Note'] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message='Note', - ) - next_page_token: str = proto.Field( - proto.STRING, - number=2, - ) - - -class DeleteNoteRequest(proto.Message): - r"""Request to delete a note. - - Attributes: - name (str): - The name of the note in the form of - ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - - -class CreateNoteRequest(proto.Message): - r"""Request to create a new note. - - Attributes: - parent (str): - The name of the project in the form of - ``projects/[PROJECT_ID]``, under which the note is to be - created. - note_id (str): - The ID to use for this note. - note (grafeas.grafeas_v1.types.Note): - The note to create. - """ - - parent: str = proto.Field( - proto.STRING, - number=1, - ) - note_id: str = proto.Field( - proto.STRING, - number=2, - ) - note: 'Note' = proto.Field( - proto.MESSAGE, - number=3, - message='Note', - ) - - -class UpdateNoteRequest(proto.Message): - r"""Request to update a note. - - Attributes: - name (str): - The name of the note in the form of - ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. - note (grafeas.grafeas_v1.types.Note): - The updated note. - update_mask (google.protobuf.field_mask_pb2.FieldMask): - The fields to update. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - note: 'Note' = proto.Field( - proto.MESSAGE, - number=2, - message='Note', - ) - update_mask: field_mask_pb2.FieldMask = proto.Field( - proto.MESSAGE, - number=3, - message=field_mask_pb2.FieldMask, - ) - - -class ListNoteOccurrencesRequest(proto.Message): - r"""Request to list occurrences for a note. - - Attributes: - name (str): - The name of the note to list occurrences for in the form of - ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. - filter (str): - The filter expression. - page_size (int): - Number of occurrences to return in the list. - page_token (str): - Token to provide to skip to a particular spot - in the list. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - filter: str = proto.Field( - proto.STRING, - number=2, - ) - page_size: int = proto.Field( - proto.INT32, - number=3, - ) - page_token: str = proto.Field( - proto.STRING, - number=4, - ) - - -class ListNoteOccurrencesResponse(proto.Message): - r"""Response for listing occurrences for a note. - - Attributes: - occurrences (MutableSequence[grafeas.grafeas_v1.types.Occurrence]): - The occurrences attached to the specified - note. - next_page_token (str): - Token to provide to skip to a particular spot - in the list. - """ - - @property - def raw_page(self): - return self - - occurrences: MutableSequence['Occurrence'] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message='Occurrence', - ) - next_page_token: str = proto.Field( - proto.STRING, - number=2, - ) - - -class BatchCreateNotesRequest(proto.Message): - r"""Request to create notes in batch. - - Attributes: - parent (str): - The name of the project in the form of - ``projects/[PROJECT_ID]``, under which the notes are to be - created. - notes (MutableMapping[str, grafeas.grafeas_v1.types.Note]): - The notes to create. Max allowed length is - 1000. - """ - - parent: str = proto.Field( - proto.STRING, - number=1, - ) - notes: MutableMapping[str, 'Note'] = proto.MapField( - proto.STRING, - proto.MESSAGE, - number=2, - message='Note', - ) - - -class BatchCreateNotesResponse(proto.Message): - r"""Response for creating notes in batch. - - Attributes: - notes (MutableSequence[grafeas.grafeas_v1.types.Note]): - The notes that were created. - """ - - notes: MutableSequence['Note'] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message='Note', - ) - - -class BatchCreateOccurrencesRequest(proto.Message): - r"""Request to create occurrences in batch. - - Attributes: - parent (str): - The name of the project in the form of - ``projects/[PROJECT_ID]``, under which the occurrences are - to be created. - occurrences (MutableSequence[grafeas.grafeas_v1.types.Occurrence]): - The occurrences to create. Max allowed length - is 1000. - """ - - parent: str = proto.Field( - proto.STRING, - number=1, - ) - occurrences: MutableSequence['Occurrence'] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message='Occurrence', - ) - - -class BatchCreateOccurrencesResponse(proto.Message): - r"""Response for creating occurrences in batch. - - Attributes: - occurrences (MutableSequence[grafeas.grafeas_v1.types.Occurrence]): - The occurrences that were created. - """ - - occurrences: MutableSequence['Occurrence'] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message='Occurrence', - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/image.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/image.py deleted file mode 100644 index 9fde99b85808..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/image.py +++ /dev/null @@ -1,158 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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='grafeas.v1', - manifest={ - 'Layer', - 'Fingerprint', - 'ImageNote', - 'ImageOccurrence', - }, -) - - -class Layer(proto.Message): - r"""Layer holds metadata specific to a layer of a Docker image. - - Attributes: - directive (str): - Required. The recovered Dockerfile directive - used to construct this layer. See - https://docs.docker.com/engine/reference/builder/ - for more information. - arguments (str): - The recovered arguments to the Dockerfile - directive. - """ - - directive: str = proto.Field( - proto.STRING, - number=1, - ) - arguments: str = proto.Field( - proto.STRING, - number=2, - ) - - -class Fingerprint(proto.Message): - r"""A set of properties that uniquely identify a given Docker - image. - - Attributes: - v1_name (str): - Required. The layer ID of the final layer in - the Docker image's v1 representation. - v2_blob (MutableSequence[str]): - Required. The ordered list of v2 blobs that - represent a given image. - v2_name (str): - Output only. The name of the image's v2 blobs computed via: - [bottom] := v2_blob[bottom] [N] := sha256(v2_blob[N] + " " + - v2_name[N+1]) Only the name of the final blob is kept. - """ - - v1_name: str = proto.Field( - proto.STRING, - number=1, - ) - v2_blob: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=2, - ) - v2_name: str = proto.Field( - proto.STRING, - number=3, - ) - - -class ImageNote(proto.Message): - r"""Basis describes the base image portion (Note) of the DockerImage - relationship. Linked occurrences are derived from this or an - equivalent image via: FROM Or an equivalent - reference, e.g., a tag of the resource_url. - - Attributes: - resource_url (str): - Required. Immutable. The resource_url for the resource - representing the basis of associated occurrence images. - fingerprint (grafeas.grafeas_v1.types.Fingerprint): - Required. Immutable. The fingerprint of the - base image. - """ - - resource_url: str = proto.Field( - proto.STRING, - number=1, - ) - fingerprint: 'Fingerprint' = proto.Field( - proto.MESSAGE, - number=2, - message='Fingerprint', - ) - - -class ImageOccurrence(proto.Message): - r"""Details of the derived image portion of the DockerImage - relationship. This image would be produced from a Dockerfile - with FROM . - - Attributes: - fingerprint (grafeas.grafeas_v1.types.Fingerprint): - Required. The fingerprint of the derived - image. - distance (int): - Output only. The number of layers by which - this image differs from the associated image - basis. - layer_info (MutableSequence[grafeas.grafeas_v1.types.Layer]): - This contains layer-specific metadata, if populated it has - length "distance" and is ordered with [distance] being the - layer immediately following the base image and [1] being the - final layer. - base_resource_url (str): - Output only. This contains the base image URL - for the derived image occurrence. - """ - - fingerprint: 'Fingerprint' = proto.Field( - proto.MESSAGE, - number=1, - message='Fingerprint', - ) - distance: int = proto.Field( - proto.INT32, - number=2, - ) - layer_info: MutableSequence['Layer'] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message='Layer', - ) - base_resource_url: str = proto.Field( - proto.STRING, - number=4, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_provenance.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_provenance.py deleted file mode 100644 index 940bd414da8f..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_provenance.py +++ /dev/null @@ -1,248 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 any_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'Recipe', - 'Completeness', - 'Metadata', - 'BuilderConfig', - 'InTotoProvenance', - }, -) - - -class Recipe(proto.Message): - r"""Steps taken to build the artifact. - For a TaskRun, typically each container corresponds to one step - in the recipe. - - Attributes: - type_ (str): - URI indicating what type of recipe was - performed. It determines the meaning of - recipe.entryPoint, recipe.arguments, - recipe.environment, and materials. - defined_in_material (int): - Index in materials containing the recipe - steps that are not implied by recipe.type. For - example, if the recipe type were "make", then - this would point to the source containing the - Makefile, not the make program itself. Set to -1 - if the recipe doesn't come from a material, as - zero is default unset value for int64. - entry_point (str): - String identifying the entry point into the - build. This is often a path to a configuration - file and/or a target label within that file. The - syntax and meaning are defined by recipe.type. - For example, if the recipe type were "make", - then this would reference the directory in which - to run make as well as which target to use. - arguments (MutableSequence[google.protobuf.any_pb2.Any]): - Collection of all external inputs that - influenced the build on top of - recipe.definedInMaterial and recipe.entryPoint. - For example, if the recipe type were "make", - then this might be the flags passed to make - aside from the target, which is captured in - recipe.entryPoint. Since the arguments field can - greatly vary in structure, depending on the - builder and recipe type, this is of form "Any". - environment (MutableSequence[google.protobuf.any_pb2.Any]): - Any other builder-controlled inputs necessary - for correctly evaluating the recipe. Usually - only needed for reproducing the build but not - evaluated as part of policy. Since the - environment field can greatly vary in structure, - depending on the builder and recipe type, this - is of form "Any". - """ - - type_: str = proto.Field( - proto.STRING, - number=1, - ) - defined_in_material: int = proto.Field( - proto.INT64, - number=2, - ) - entry_point: str = proto.Field( - proto.STRING, - number=3, - ) - arguments: MutableSequence[any_pb2.Any] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message=any_pb2.Any, - ) - environment: MutableSequence[any_pb2.Any] = proto.RepeatedField( - proto.MESSAGE, - number=5, - message=any_pb2.Any, - ) - - -class Completeness(proto.Message): - r"""Indicates that the builder claims certain fields in this - message to be complete. - - Attributes: - arguments (bool): - If true, the builder claims that - recipe.arguments is complete, meaning that all - external inputs are properly captured in the - recipe. - environment (bool): - If true, the builder claims that - recipe.environment is claimed to be complete. - materials (bool): - If true, the builder claims that materials - are complete, usually through some controls to - prevent network access. Sometimes called - "hermetic". - """ - - arguments: bool = proto.Field( - proto.BOOL, - number=1, - ) - environment: bool = proto.Field( - proto.BOOL, - number=2, - ) - materials: bool = proto.Field( - proto.BOOL, - number=3, - ) - - -class Metadata(proto.Message): - r"""Other properties of the build. - - Attributes: - build_invocation_id (str): - Identifies the particular build invocation, - which can be useful for finding associated logs - or other ad-hoc analysis. The value SHOULD be - globally unique, per in-toto Provenance spec. - build_started_on (google.protobuf.timestamp_pb2.Timestamp): - The timestamp of when the build started. - build_finished_on (google.protobuf.timestamp_pb2.Timestamp): - The timestamp of when the build completed. - completeness (grafeas.grafeas_v1.types.Completeness): - Indicates that the builder claims certain - fields in this message to be complete. - reproducible (bool): - If true, the builder claims that running the - recipe on materials will produce bit-for-bit - identical output. - """ - - build_invocation_id: str = proto.Field( - proto.STRING, - number=1, - ) - build_started_on: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=2, - message=timestamp_pb2.Timestamp, - ) - build_finished_on: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=3, - message=timestamp_pb2.Timestamp, - ) - completeness: 'Completeness' = proto.Field( - proto.MESSAGE, - number=4, - message='Completeness', - ) - reproducible: bool = proto.Field( - proto.BOOL, - number=5, - ) - - -class BuilderConfig(proto.Message): - r""" - - Attributes: - id (str): - - """ - - id: str = proto.Field( - proto.STRING, - number=1, - ) - - -class InTotoProvenance(proto.Message): - r""" - - Attributes: - builder_config (grafeas.grafeas_v1.types.BuilderConfig): - required - recipe (grafeas.grafeas_v1.types.Recipe): - Identifies the configuration used for the - build. When combined with materials, this SHOULD - fully describe the build, such that re-running - this recipe results in bit-for-bit identical - output (if the build is reproducible). - metadata (grafeas.grafeas_v1.types.Metadata): - - materials (MutableSequence[str]): - The collection of artifacts that influenced - the build including sources, dependencies, build - tools, base images, and so on. This is - considered to be incomplete unless - metadata.completeness.materials is true. Unset - or null is equivalent to empty. - """ - - builder_config: 'BuilderConfig' = proto.Field( - proto.MESSAGE, - number=1, - message='BuilderConfig', - ) - recipe: 'Recipe' = proto.Field( - proto.MESSAGE, - number=2, - message='Recipe', - ) - metadata: 'Metadata' = proto.Field( - proto.MESSAGE, - number=3, - message='Metadata', - ) - materials: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=4, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_statement.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_statement.py deleted file mode 100644 index d42bddb2cdf9..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/intoto_statement.py +++ /dev/null @@ -1,353 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 struct_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -from grafeas.grafeas_v1.types import intoto_provenance -from grafeas.grafeas_v1.types import slsa_provenance as g_slsa_provenance -from grafeas.grafeas_v1.types import slsa_provenance_zero_two as g_slsa_provenance_zero_two - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'InTotoStatement', - 'Subject', - 'InTotoSlsaProvenanceV1', - }, -) - - -class InTotoStatement(proto.Message): - r"""Spec defined at - https://github.com/in-toto/attestation/tree/main/spec#statement - The serialized InTotoStatement will be stored as - Envelope.payload. Envelope.payloadType is always - "application/vnd.in-toto+json". - - 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: - type_ (str): - Always ``https://in-toto.io/Statement/v0.1``. - subject (MutableSequence[grafeas.grafeas_v1.types.Subject]): - - predicate_type (str): - ``https://slsa.dev/provenance/v0.1`` for SlsaProvenance. - provenance (grafeas.grafeas_v1.types.InTotoProvenance): - - This field is a member of `oneof`_ ``predicate``. - slsa_provenance (grafeas.grafeas_v1.types.SlsaProvenance): - - This field is a member of `oneof`_ ``predicate``. - slsa_provenance_zero_two (grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo): - - This field is a member of `oneof`_ ``predicate``. - """ - - type_: str = proto.Field( - proto.STRING, - number=1, - ) - subject: MutableSequence['Subject'] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message='Subject', - ) - predicate_type: str = proto.Field( - proto.STRING, - number=3, - ) - provenance: intoto_provenance.InTotoProvenance = proto.Field( - proto.MESSAGE, - number=4, - oneof='predicate', - message=intoto_provenance.InTotoProvenance, - ) - slsa_provenance: g_slsa_provenance.SlsaProvenance = proto.Field( - proto.MESSAGE, - number=5, - oneof='predicate', - message=g_slsa_provenance.SlsaProvenance, - ) - slsa_provenance_zero_two: g_slsa_provenance_zero_two.SlsaProvenanceZeroTwo = proto.Field( - proto.MESSAGE, - number=6, - oneof='predicate', - message=g_slsa_provenance_zero_two.SlsaProvenanceZeroTwo, - ) - - -class Subject(proto.Message): - r""" - - Attributes: - name (str): - - digest (MutableMapping[str, str]): - ``"": ""`` Algorithms can be e.g. - sha256, sha512 See - https://github.com/in-toto/attestation/blob/main/spec/field_types.md#DigestSet - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - digest: MutableMapping[str, str] = proto.MapField( - proto.STRING, - proto.STRING, - number=2, - ) - - -class InTotoSlsaProvenanceV1(proto.Message): - r""" - - Attributes: - type_ (str): - InToto spec defined at - https://github.com/in-toto/attestation/tree/main/spec#statement - subject (MutableSequence[grafeas.grafeas_v1.types.Subject]): - - predicate_type (str): - - predicate (grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.SlsaProvenanceV1): - - """ - - class SlsaProvenanceV1(proto.Message): - r"""Keep in sync with schema at - https://github.com/slsa-framework/slsa/blob/main/docs/provenance/schema/v1/provenance.proto - Builder renamed to ProvenanceBuilder because of Java conflicts. - - Attributes: - build_definition (grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.BuildDefinition): - - run_details (grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.RunDetails): - - """ - - build_definition: 'InTotoSlsaProvenanceV1.BuildDefinition' = proto.Field( - proto.MESSAGE, - number=1, - message='InTotoSlsaProvenanceV1.BuildDefinition', - ) - run_details: 'InTotoSlsaProvenanceV1.RunDetails' = proto.Field( - proto.MESSAGE, - number=2, - message='InTotoSlsaProvenanceV1.RunDetails', - ) - - class BuildDefinition(proto.Message): - r""" - - Attributes: - build_type (str): - - external_parameters (google.protobuf.struct_pb2.Struct): - - internal_parameters (google.protobuf.struct_pb2.Struct): - - resolved_dependencies (MutableSequence[grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.ResourceDescriptor]): - - """ - - build_type: str = proto.Field( - proto.STRING, - number=1, - ) - external_parameters: struct_pb2.Struct = proto.Field( - proto.MESSAGE, - number=2, - message=struct_pb2.Struct, - ) - internal_parameters: struct_pb2.Struct = proto.Field( - proto.MESSAGE, - number=3, - message=struct_pb2.Struct, - ) - resolved_dependencies: MutableSequence['InTotoSlsaProvenanceV1.ResourceDescriptor'] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message='InTotoSlsaProvenanceV1.ResourceDescriptor', - ) - - class ResourceDescriptor(proto.Message): - r""" - - Attributes: - name (str): - - uri (str): - - digest (MutableMapping[str, str]): - - content (bytes): - - download_location (str): - - media_type (str): - - annotations (MutableMapping[str, google.protobuf.struct_pb2.Value]): - - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - uri: str = proto.Field( - proto.STRING, - number=2, - ) - digest: MutableMapping[str, str] = proto.MapField( - proto.STRING, - proto.STRING, - number=3, - ) - content: bytes = proto.Field( - proto.BYTES, - number=4, - ) - download_location: str = proto.Field( - proto.STRING, - number=5, - ) - media_type: str = proto.Field( - proto.STRING, - number=6, - ) - annotations: MutableMapping[str, struct_pb2.Value] = proto.MapField( - proto.STRING, - proto.MESSAGE, - number=7, - message=struct_pb2.Value, - ) - - class RunDetails(proto.Message): - r""" - - Attributes: - builder (grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.ProvenanceBuilder): - - metadata (grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.BuildMetadata): - - byproducts (MutableSequence[grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.ResourceDescriptor]): - - """ - - builder: 'InTotoSlsaProvenanceV1.ProvenanceBuilder' = proto.Field( - proto.MESSAGE, - number=1, - message='InTotoSlsaProvenanceV1.ProvenanceBuilder', - ) - metadata: 'InTotoSlsaProvenanceV1.BuildMetadata' = proto.Field( - proto.MESSAGE, - number=2, - message='InTotoSlsaProvenanceV1.BuildMetadata', - ) - byproducts: MutableSequence['InTotoSlsaProvenanceV1.ResourceDescriptor'] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message='InTotoSlsaProvenanceV1.ResourceDescriptor', - ) - - class ProvenanceBuilder(proto.Message): - r""" - - Attributes: - id (str): - - version (MutableMapping[str, str]): - - builder_dependencies (MutableSequence[grafeas.grafeas_v1.types.InTotoSlsaProvenanceV1.ResourceDescriptor]): - - """ - - id: str = proto.Field( - proto.STRING, - number=1, - ) - version: MutableMapping[str, str] = proto.MapField( - proto.STRING, - proto.STRING, - number=2, - ) - builder_dependencies: MutableSequence['InTotoSlsaProvenanceV1.ResourceDescriptor'] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message='InTotoSlsaProvenanceV1.ResourceDescriptor', - ) - - class BuildMetadata(proto.Message): - r""" - - Attributes: - invocation_id (str): - - started_on (google.protobuf.timestamp_pb2.Timestamp): - - finished_on (google.protobuf.timestamp_pb2.Timestamp): - - """ - - invocation_id: str = proto.Field( - proto.STRING, - number=1, - ) - started_on: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=2, - message=timestamp_pb2.Timestamp, - ) - finished_on: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=3, - message=timestamp_pb2.Timestamp, - ) - - type_: str = proto.Field( - proto.STRING, - number=1, - ) - subject: MutableSequence['Subject'] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message='Subject', - ) - predicate_type: str = proto.Field( - proto.STRING, - number=3, - ) - predicate: SlsaProvenanceV1 = proto.Field( - proto.MESSAGE, - number=4, - message=SlsaProvenanceV1, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/package.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/package.py deleted file mode 100644 index d2402a958a94..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/package.py +++ /dev/null @@ -1,378 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import common - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'Architecture', - 'Distribution', - 'Location', - 'PackageNote', - 'PackageOccurrence', - 'Version', - }, -) - - -class Architecture(proto.Enum): - r"""Instruction set architectures supported by various package - managers. - - Values: - ARCHITECTURE_UNSPECIFIED (0): - Unknown architecture. - X86 (1): - X86 architecture. - X64 (2): - X64 architecture. - """ - ARCHITECTURE_UNSPECIFIED = 0 - X86 = 1 - X64 = 2 - - -class Distribution(proto.Message): - r"""This represents a particular channel of distribution for a - given package. E.g., Debian's jessie-backports dpkg mirror. - - Attributes: - cpe_uri (str): - The cpe_uri in `CPE - format `__ denoting - the package manager version distributing a package. - architecture (grafeas.grafeas_v1.types.Architecture): - The CPU architecture for which packages in - this distribution channel were built. - latest_version (grafeas.grafeas_v1.types.Version): - The latest available version of this package - in this distribution channel. - maintainer (str): - A freeform string denoting the maintainer of - this package. - url (str): - The distribution channel-specific homepage - for this package. - description (str): - The distribution channel-specific description - of this package. - """ - - cpe_uri: str = proto.Field( - proto.STRING, - number=1, - ) - architecture: 'Architecture' = proto.Field( - proto.ENUM, - number=2, - enum='Architecture', - ) - latest_version: 'Version' = proto.Field( - proto.MESSAGE, - number=3, - message='Version', - ) - maintainer: str = proto.Field( - proto.STRING, - number=4, - ) - url: str = proto.Field( - proto.STRING, - number=5, - ) - description: str = proto.Field( - proto.STRING, - number=6, - ) - - -class Location(proto.Message): - r"""An occurrence of a particular package installation found within a - system's filesystem. E.g., glibc was found in - ``/var/lib/dpkg/status``. - - Attributes: - cpe_uri (str): - Deprecated. The CPE URI in `CPE - format `__ - version (grafeas.grafeas_v1.types.Version): - Deprecated. - The version installed at this location. - path (str): - The path from which we gathered that this - package/version is installed. - """ - - cpe_uri: str = proto.Field( - proto.STRING, - number=1, - ) - version: 'Version' = proto.Field( - proto.MESSAGE, - number=2, - message='Version', - ) - path: str = proto.Field( - proto.STRING, - number=3, - ) - - -class PackageNote(proto.Message): - r"""PackageNote represents a particular package version. - - Attributes: - name (str): - The name of the package. - distribution (MutableSequence[grafeas.grafeas_v1.types.Distribution]): - Deprecated. - The various channels by which a package is - distributed. - package_type (str): - The type of package; whether native or non - native (e.g., ruby gems, node.js packages, - etc.). - cpe_uri (str): - The cpe_uri in `CPE - format `__ denoting - the package manager version distributing a package. The - cpe_uri will be blank for language packages. - architecture (grafeas.grafeas_v1.types.Architecture): - The CPU architecture for which packages in - this distribution channel were built. - Architecture will be blank for language - packages. - version (grafeas.grafeas_v1.types.Version): - The version of the package. - maintainer (str): - A freeform text denoting the maintainer of - this package. - url (str): - The homepage for this package. - description (str): - The description of this package. - license_ (grafeas.grafeas_v1.types.License): - Licenses that have been declared by the - authors of the package. - digest (MutableSequence[grafeas.grafeas_v1.types.Digest]): - Hash value, typically a file digest, that - allows unique identification a specific package. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - distribution: MutableSequence['Distribution'] = proto.RepeatedField( - proto.MESSAGE, - number=10, - message='Distribution', - ) - package_type: str = proto.Field( - proto.STRING, - number=11, - ) - cpe_uri: str = proto.Field( - proto.STRING, - number=12, - ) - architecture: 'Architecture' = proto.Field( - proto.ENUM, - number=13, - enum='Architecture', - ) - version: 'Version' = proto.Field( - proto.MESSAGE, - number=14, - message='Version', - ) - maintainer: str = proto.Field( - proto.STRING, - number=15, - ) - url: str = proto.Field( - proto.STRING, - number=16, - ) - description: str = proto.Field( - proto.STRING, - number=17, - ) - license_: common.License = proto.Field( - proto.MESSAGE, - number=18, - message=common.License, - ) - digest: MutableSequence[common.Digest] = proto.RepeatedField( - proto.MESSAGE, - number=19, - message=common.Digest, - ) - - -class PackageOccurrence(proto.Message): - r"""Details on how a particular software package was installed on - a system. - - Attributes: - name (str): - The name of the installed package. - location (MutableSequence[grafeas.grafeas_v1.types.Location]): - All of the places within the filesystem - versions of this package have been found. - package_type (str): - The type of package; whether native or non - native (e.g., ruby gems, node.js packages, - etc.). - cpe_uri (str): - The cpe_uri in `CPE - format `__ denoting - the package manager version distributing a package. The - cpe_uri will be blank for language packages. - architecture (grafeas.grafeas_v1.types.Architecture): - The CPU architecture for which packages in - this distribution channel were built. - Architecture will be blank for language - packages. - license_ (grafeas.grafeas_v1.types.License): - Licenses that have been declared by the - authors of the package. - version (grafeas.grafeas_v1.types.Version): - The version of the package. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - location: MutableSequence['Location'] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message='Location', - ) - package_type: str = proto.Field( - proto.STRING, - number=3, - ) - cpe_uri: str = proto.Field( - proto.STRING, - number=4, - ) - architecture: 'Architecture' = proto.Field( - proto.ENUM, - number=5, - enum='Architecture', - ) - license_: common.License = proto.Field( - proto.MESSAGE, - number=6, - message=common.License, - ) - version: 'Version' = proto.Field( - proto.MESSAGE, - number=7, - message='Version', - ) - - -class Version(proto.Message): - r"""Version contains structured information about the version of - a package. - - Attributes: - epoch (int): - Used to correct mistakes in the version - numbering scheme. - name (str): - Required only when version kind is NORMAL. - The main part of the version name. - revision (str): - The iteration of the package build from the - above version. - inclusive (bool): - Whether this version is specifying part of an - inclusive range. Grafeas does not have the - capability to specify version ranges; instead we - have fields that specify start version and end - versions. At times this is insufficient - we - also need to specify whether the version is - included in the range or is excluded from the - range. This boolean is expected to be set to - true when the version is included in a range. - kind (grafeas.grafeas_v1.types.Version.VersionKind): - Required. Distinguishes between sentinel - MIN/MAX versions and normal versions. - full_name (str): - Human readable version string. This string is - of the form :- and is - only set when kind is NORMAL. - """ - class VersionKind(proto.Enum): - r"""Whether this is an ordinary package version or a sentinel - MIN/MAX version. - - Values: - VERSION_KIND_UNSPECIFIED (0): - Unknown. - NORMAL (1): - A standard package version. - MINIMUM (2): - A special version representing negative - infinity. - MAXIMUM (3): - A special version representing positive - infinity. - """ - VERSION_KIND_UNSPECIFIED = 0 - NORMAL = 1 - MINIMUM = 2 - MAXIMUM = 3 - - epoch: int = proto.Field( - proto.INT32, - number=1, - ) - name: str = proto.Field( - proto.STRING, - number=2, - ) - revision: str = proto.Field( - proto.STRING, - number=3, - ) - inclusive: bool = proto.Field( - proto.BOOL, - number=6, - ) - kind: VersionKind = proto.Field( - proto.ENUM, - number=4, - enum=VersionKind, - ) - full_name: str = proto.Field( - proto.STRING, - number=5, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/provenance.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/provenance.py deleted file mode 100644 index b09cbad6cbdd..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/provenance.py +++ /dev/null @@ -1,597 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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='grafeas.v1', - manifest={ - 'BuildProvenance', - 'Source', - 'FileHashes', - 'Hash', - 'Command', - 'Artifact', - 'SourceContext', - 'AliasContext', - 'CloudRepoSourceContext', - 'GerritSourceContext', - 'GitSourceContext', - 'RepoId', - 'ProjectRepoId', - }, -) - - -class BuildProvenance(proto.Message): - r"""Provenance of a build. Contains all information needed to - verify the full details about the build from source to - completion. - - Attributes: - id (str): - Required. Unique identifier of the build. - project_id (str): - ID of the project. - commands (MutableSequence[grafeas.grafeas_v1.types.Command]): - Commands requested by the build. - built_artifacts (MutableSequence[grafeas.grafeas_v1.types.Artifact]): - Output of the build. - create_time (google.protobuf.timestamp_pb2.Timestamp): - Time at which the build was created. - start_time (google.protobuf.timestamp_pb2.Timestamp): - Time at which execution of the build was - started. - end_time (google.protobuf.timestamp_pb2.Timestamp): - Time at which execution of the build was - finished. - creator (str): - E-mail address of the user who initiated this - build. Note that this was the user's e-mail - address at the time the build was initiated; - this address may not represent the same end-user - for all time. - logs_uri (str): - URI where any logs for this provenance were - written. - source_provenance (grafeas.grafeas_v1.types.Source): - Details of the Source input to the build. - trigger_id (str): - Trigger identifier if the build was triggered - automatically; empty if not. - build_options (MutableMapping[str, str]): - Special options applied to this build. This - is a catch-all field where build providers can - enter any desired additional details. - builder_version (str): - Version string of the builder at the time - this build was executed. - """ - - id: str = proto.Field( - proto.STRING, - number=1, - ) - project_id: str = proto.Field( - proto.STRING, - number=2, - ) - commands: MutableSequence['Command'] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message='Command', - ) - built_artifacts: MutableSequence['Artifact'] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message='Artifact', - ) - create_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=5, - message=timestamp_pb2.Timestamp, - ) - start_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=6, - message=timestamp_pb2.Timestamp, - ) - end_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=7, - message=timestamp_pb2.Timestamp, - ) - creator: str = proto.Field( - proto.STRING, - number=8, - ) - logs_uri: str = proto.Field( - proto.STRING, - number=9, - ) - source_provenance: 'Source' = proto.Field( - proto.MESSAGE, - number=10, - message='Source', - ) - trigger_id: str = proto.Field( - proto.STRING, - number=11, - ) - build_options: MutableMapping[str, str] = proto.MapField( - proto.STRING, - proto.STRING, - number=12, - ) - builder_version: str = proto.Field( - proto.STRING, - number=13, - ) - - -class Source(proto.Message): - r"""Source describes the location of the source used for the - build. - - Attributes: - artifact_storage_source_uri (str): - If provided, the input binary artifacts for - the build came from this location. - file_hashes (MutableMapping[str, grafeas.grafeas_v1.types.FileHashes]): - Hash(es) of the build source, which can be - used to verify that the original source - integrity was maintained in the build. - - The keys to this map are file paths used as - build source and the values contain the hash - values for those files. - - If the build source came in a single package - such as a gzipped tarfile (.tar.gz), the - FileHash will be for the single path to that - file. - context (grafeas.grafeas_v1.types.SourceContext): - If provided, the source code used for the - build came from this location. - additional_contexts (MutableSequence[grafeas.grafeas_v1.types.SourceContext]): - If provided, some of the source code used for - the build may be found in these locations, in - the case where the source repository had - multiple remotes or submodules. This list will - not include the context specified in the context - field. - """ - - artifact_storage_source_uri: str = proto.Field( - proto.STRING, - number=1, - ) - file_hashes: MutableMapping[str, 'FileHashes'] = proto.MapField( - proto.STRING, - proto.MESSAGE, - number=2, - message='FileHashes', - ) - context: 'SourceContext' = proto.Field( - proto.MESSAGE, - number=3, - message='SourceContext', - ) - additional_contexts: MutableSequence['SourceContext'] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message='SourceContext', - ) - - -class FileHashes(proto.Message): - r"""Container message for hashes of byte content of files, used - in source messages to verify integrity of source input to the - build. - - Attributes: - file_hash (MutableSequence[grafeas.grafeas_v1.types.Hash]): - Required. Collection of file hashes. - """ - - file_hash: MutableSequence['Hash'] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message='Hash', - ) - - -class Hash(proto.Message): - r"""Container message for hash values. - - Attributes: - type_ (str): - Required. The type of hash that was - performed, e.g. "SHA-256". - value (bytes): - Required. The hash value. - """ - - type_: str = proto.Field( - proto.STRING, - number=1, - ) - value: bytes = proto.Field( - proto.BYTES, - number=2, - ) - - -class Command(proto.Message): - r"""Command describes a step performed as part of the build - pipeline. - - Attributes: - name (str): - Required. Name of the command, as presented on the command - line, or if the command is packaged as a Docker container, - as presented to ``docker pull``. - env (MutableSequence[str]): - Environment variables set before running this - command. - args (MutableSequence[str]): - Command-line arguments used when executing - this command. - dir_ (str): - Working directory (relative to project source - root) used when running this command. - id (str): - Optional unique identifier for this command, used in - wait_for to reference this command as a dependency. - wait_for (MutableSequence[str]): - The ID(s) of the command(s) that this command - depends on. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - env: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=2, - ) - args: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=3, - ) - dir_: str = proto.Field( - proto.STRING, - number=4, - ) - id: str = proto.Field( - proto.STRING, - number=5, - ) - wait_for: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=6, - ) - - -class Artifact(proto.Message): - r"""Artifact describes a build product. - - Attributes: - checksum (str): - Hash or checksum value of a binary, or Docker - Registry 2.0 digest of a container. - id (str): - Artifact ID, if any; for container images, this will be a - URL by digest like - ``gcr.io/projectID/imagename@sha256:123456``. - names (MutableSequence[str]): - Related artifact names. This may be the path to a binary or - jar file, or in the case of a container build, the name used - to push the container image to Google Container Registry, as - presented to ``docker push``. Note that a single Artifact ID - can have multiple names, for example if two tags are applied - to one image. - """ - - checksum: str = proto.Field( - proto.STRING, - number=1, - ) - id: str = proto.Field( - proto.STRING, - number=2, - ) - names: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=3, - ) - - -class SourceContext(proto.Message): - r"""A SourceContext is a reference to a tree of files. A - SourceContext together with a path point to a unique revision of - a single file or directory. - - 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: - cloud_repo (grafeas.grafeas_v1.types.CloudRepoSourceContext): - A SourceContext referring to a revision in a - Google Cloud Source Repo. - - This field is a member of `oneof`_ ``context``. - gerrit (grafeas.grafeas_v1.types.GerritSourceContext): - A SourceContext referring to a Gerrit - project. - - This field is a member of `oneof`_ ``context``. - git (grafeas.grafeas_v1.types.GitSourceContext): - A SourceContext referring to any third party - Git repo (e.g., GitHub). - - This field is a member of `oneof`_ ``context``. - labels (MutableMapping[str, str]): - Labels with user defined metadata. - """ - - cloud_repo: 'CloudRepoSourceContext' = proto.Field( - proto.MESSAGE, - number=1, - oneof='context', - message='CloudRepoSourceContext', - ) - gerrit: 'GerritSourceContext' = proto.Field( - proto.MESSAGE, - number=2, - oneof='context', - message='GerritSourceContext', - ) - git: 'GitSourceContext' = proto.Field( - proto.MESSAGE, - number=3, - oneof='context', - message='GitSourceContext', - ) - labels: MutableMapping[str, str] = proto.MapField( - proto.STRING, - proto.STRING, - number=4, - ) - - -class AliasContext(proto.Message): - r"""An alias to a repo revision. - - Attributes: - kind (grafeas.grafeas_v1.types.AliasContext.Kind): - The alias kind. - name (str): - The alias name. - """ - class Kind(proto.Enum): - r"""The type of an alias. - - Values: - KIND_UNSPECIFIED (0): - Unknown. - FIXED (1): - Git tag. - MOVABLE (2): - Git branch. - OTHER (4): - Used to specify non-standard aliases. For - example, if a Git repo has a ref named - "refs/foo/bar". - """ - KIND_UNSPECIFIED = 0 - FIXED = 1 - MOVABLE = 2 - OTHER = 4 - - kind: Kind = proto.Field( - proto.ENUM, - number=1, - enum=Kind, - ) - name: str = proto.Field( - proto.STRING, - number=2, - ) - - -class CloudRepoSourceContext(proto.Message): - r"""A CloudRepoSourceContext denotes a particular revision in a - Google Cloud Source Repo. - - 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: - repo_id (grafeas.grafeas_v1.types.RepoId): - The ID of the repo. - revision_id (str): - A revision ID. - - This field is a member of `oneof`_ ``revision``. - alias_context (grafeas.grafeas_v1.types.AliasContext): - An alias, which may be a branch or tag. - - This field is a member of `oneof`_ ``revision``. - """ - - repo_id: 'RepoId' = proto.Field( - proto.MESSAGE, - number=1, - message='RepoId', - ) - revision_id: str = proto.Field( - proto.STRING, - number=2, - oneof='revision', - ) - alias_context: 'AliasContext' = proto.Field( - proto.MESSAGE, - number=3, - oneof='revision', - message='AliasContext', - ) - - -class GerritSourceContext(proto.Message): - r"""A SourceContext referring to a Gerrit project. - - 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: - host_uri (str): - The URI of a running Gerrit instance. - gerrit_project (str): - The full project name within the host. - Projects may be nested, so "project/subproject" - is a valid project name. The "repo name" is the - hostURI/project. - revision_id (str): - A revision (commit) ID. - - This field is a member of `oneof`_ ``revision``. - alias_context (grafeas.grafeas_v1.types.AliasContext): - An alias, which may be a branch or tag. - - This field is a member of `oneof`_ ``revision``. - """ - - host_uri: str = proto.Field( - proto.STRING, - number=1, - ) - gerrit_project: str = proto.Field( - proto.STRING, - number=2, - ) - revision_id: str = proto.Field( - proto.STRING, - number=3, - oneof='revision', - ) - alias_context: 'AliasContext' = proto.Field( - proto.MESSAGE, - number=4, - oneof='revision', - message='AliasContext', - ) - - -class GitSourceContext(proto.Message): - r"""A GitSourceContext denotes a particular revision in a third - party Git repository (e.g., GitHub). - - Attributes: - url (str): - Git repository URL. - revision_id (str): - Git commit hash. - """ - - url: str = proto.Field( - proto.STRING, - number=1, - ) - revision_id: str = proto.Field( - proto.STRING, - number=2, - ) - - -class RepoId(proto.Message): - r"""A unique identifier for a Cloud Repo. - - 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: - project_repo_id (grafeas.grafeas_v1.types.ProjectRepoId): - A combination of a project ID and a repo - name. - - This field is a member of `oneof`_ ``id``. - uid (str): - A server-assigned, globally unique - identifier. - - This field is a member of `oneof`_ ``id``. - """ - - project_repo_id: 'ProjectRepoId' = proto.Field( - proto.MESSAGE, - number=1, - oneof='id', - message='ProjectRepoId', - ) - uid: str = proto.Field( - proto.STRING, - number=2, - oneof='id', - ) - - -class ProjectRepoId(proto.Message): - r"""Selects a repo using a Google Cloud Platform project ID - (e.g., winged-cargo-31) and a repo name within that project. - - Attributes: - project_id (str): - The ID of the project. - repo_name (str): - The name of the repo. Leave empty for the - default repo. - """ - - project_id: str = proto.Field( - proto.STRING, - number=1, - ) - repo_name: str = proto.Field( - proto.STRING, - number=2, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/sbom.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/sbom.py deleted file mode 100644 index e4e85214f8c7..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/sbom.py +++ /dev/null @@ -1,171 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import common -from grafeas.grafeas_v1.types import intoto_statement - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'SBOMReferenceNote', - 'SBOMReferenceOccurrence', - 'SbomReferenceIntotoPayload', - 'SbomReferenceIntotoPredicate', - }, -) - - -class SBOMReferenceNote(proto.Message): - r"""The note representing an SBOM reference. - - Attributes: - format_ (str): - The format that SBOM takes. E.g. may be spdx, - cyclonedx, etc... - version (str): - The version of the format that the SBOM - takes. E.g. if the format is spdx, the version - may be 2.3. - """ - - format_: str = proto.Field( - proto.STRING, - number=1, - ) - version: str = proto.Field( - proto.STRING, - number=2, - ) - - -class SBOMReferenceOccurrence(proto.Message): - r"""The occurrence representing an SBOM reference as applied to a - specific resource. The occurrence follows the DSSE - specification. See - https://github.com/secure-systems-lab/dsse/blob/master/envelope.md - for more details. - - Attributes: - payload (grafeas.grafeas_v1.types.SbomReferenceIntotoPayload): - The actual payload that contains the SBOM - reference data. - payload_type (str): - The kind of payload that - SbomReferenceIntotoPayload takes. Since it's in - the intoto format, this value is expected to be - 'application/vnd.in-toto+json'. - signatures (MutableSequence[grafeas.grafeas_v1.types.EnvelopeSignature]): - The signatures over the payload. - """ - - payload: 'SbomReferenceIntotoPayload' = proto.Field( - proto.MESSAGE, - number=1, - message='SbomReferenceIntotoPayload', - ) - payload_type: str = proto.Field( - proto.STRING, - number=2, - ) - signatures: MutableSequence[common.EnvelopeSignature] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message=common.EnvelopeSignature, - ) - - -class SbomReferenceIntotoPayload(proto.Message): - r"""The actual payload that contains the SBOM Reference data. - The payload follows the intoto statement specification. See - https://github.com/in-toto/attestation/blob/main/spec/v1.0/statement.md - for more details. - - Attributes: - type_ (str): - Identifier for the schema of the Statement. - predicate_type (str): - URI identifying the type of the Predicate. - subject (MutableSequence[grafeas.grafeas_v1.types.Subject]): - Set of software artifacts that the - attestation applies to. Each element represents - a single software artifact. - predicate (grafeas.grafeas_v1.types.SbomReferenceIntotoPredicate): - Additional parameters of the Predicate. - Includes the actual data about the SBOM. - """ - - type_: str = proto.Field( - proto.STRING, - number=1, - ) - predicate_type: str = proto.Field( - proto.STRING, - number=2, - ) - subject: MutableSequence[intoto_statement.Subject] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message=intoto_statement.Subject, - ) - predicate: 'SbomReferenceIntotoPredicate' = proto.Field( - proto.MESSAGE, - number=4, - message='SbomReferenceIntotoPredicate', - ) - - -class SbomReferenceIntotoPredicate(proto.Message): - r"""A predicate which describes the SBOM being referenced. - - Attributes: - referrer_id (str): - The person or system referring this predicate - to the consumer. - location (str): - The location of the SBOM. - mime_type (str): - The mime type of the SBOM. - digest (MutableMapping[str, str]): - A map of algorithm to digest of the contents - of the SBOM. - """ - - referrer_id: str = proto.Field( - proto.STRING, - number=1, - ) - location: str = proto.Field( - proto.STRING, - number=2, - ) - mime_type: str = proto.Field( - proto.STRING, - number=3, - ) - digest: MutableMapping[str, str] = proto.MapField( - proto.STRING, - proto.STRING, - number=4, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/severity.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/severity.py deleted file mode 100644 index cee526950a5c..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/severity.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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='grafeas.v1', - manifest={ - 'Severity', - }, -) - - -class Severity(proto.Enum): - r"""Note provider assigned severity/impact ranking. - - Values: - SEVERITY_UNSPECIFIED (0): - Unknown. - MINIMAL (1): - Minimal severity. - LOW (2): - Low severity. - MEDIUM (3): - Medium severity. - HIGH (4): - High severity. - CRITICAL (5): - Critical severity. - """ - SEVERITY_UNSPECIFIED = 0 - MINIMAL = 1 - LOW = 2 - MEDIUM = 3 - HIGH = 4 - CRITICAL = 5 - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance.py deleted file mode 100644 index 9284bfed9ae0..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance.py +++ /dev/null @@ -1,258 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 any_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'SlsaProvenance', - }, -) - - -class SlsaProvenance(proto.Message): - r""" - - Attributes: - builder (grafeas.grafeas_v1.types.SlsaProvenance.SlsaBuilder): - required - recipe (grafeas.grafeas_v1.types.SlsaProvenance.SlsaRecipe): - Identifies the configuration used for the - build. When combined with materials, this SHOULD - fully describe the build, such that re-running - this recipe results in bit-for-bit identical - output (if the build is reproducible). - metadata (grafeas.grafeas_v1.types.SlsaProvenance.SlsaMetadata): - - materials (MutableSequence[grafeas.grafeas_v1.types.SlsaProvenance.Material]): - The collection of artifacts that influenced - the build including sources, dependencies, build - tools, base images, and so on. This is - considered to be incomplete unless - metadata.completeness.materials is true. Unset - or null is equivalent to empty. - """ - - class SlsaRecipe(proto.Message): - r"""Steps taken to build the artifact. - For a TaskRun, typically each container corresponds to one step - in the recipe. - - Attributes: - type_ (str): - URI indicating what type of recipe was - performed. It determines the meaning of - recipe.entryPoint, recipe.arguments, - recipe.environment, and materials. - defined_in_material (int): - Index in materials containing the recipe - steps that are not implied by recipe.type. For - example, if the recipe type were "make", then - this would point to the source containing the - Makefile, not the make program itself. Set to -1 - if the recipe doesn't come from a material, as - zero is default unset value for int64. - entry_point (str): - String identifying the entry point into the - build. This is often a path to a configuration - file and/or a target label within that file. The - syntax and meaning are defined by recipe.type. - For example, if the recipe type were "make", - then this would reference the directory in which - to run make as well as which target to use. - arguments (google.protobuf.any_pb2.Any): - Collection of all external inputs that - influenced the build on top of - recipe.definedInMaterial and recipe.entryPoint. - For example, if the recipe type were "make", - then this might be the flags passed to make - aside from the target, which is captured in - recipe.entryPoint. Depending on the recipe Type, - the structure may be different. - environment (google.protobuf.any_pb2.Any): - Any other builder-controlled inputs necessary - for correctly evaluating the recipe. Usually - only needed for reproducing the build but not - evaluated as part of policy. Depending on the - recipe Type, the structure may be different. - """ - - type_: str = proto.Field( - proto.STRING, - number=1, - ) - defined_in_material: int = proto.Field( - proto.INT64, - number=2, - ) - entry_point: str = proto.Field( - proto.STRING, - number=3, - ) - arguments: any_pb2.Any = proto.Field( - proto.MESSAGE, - number=4, - message=any_pb2.Any, - ) - environment: any_pb2.Any = proto.Field( - proto.MESSAGE, - number=5, - message=any_pb2.Any, - ) - - class SlsaCompleteness(proto.Message): - r"""Indicates that the builder claims certain fields in this - message to be complete. - - Attributes: - arguments (bool): - If true, the builder claims that - recipe.arguments is complete, meaning that all - external inputs are properly captured in the - recipe. - environment (bool): - If true, the builder claims that - recipe.environment is claimed to be complete. - materials (bool): - If true, the builder claims that materials - are complete, usually through some controls to - prevent network access. Sometimes called - "hermetic". - """ - - arguments: bool = proto.Field( - proto.BOOL, - number=1, - ) - environment: bool = proto.Field( - proto.BOOL, - number=2, - ) - materials: bool = proto.Field( - proto.BOOL, - number=3, - ) - - class SlsaMetadata(proto.Message): - r"""Other properties of the build. - - Attributes: - build_invocation_id (str): - Identifies the particular build invocation, - which can be useful for finding associated logs - or other ad-hoc analysis. The value SHOULD be - globally unique, per in-toto Provenance spec. - build_started_on (google.protobuf.timestamp_pb2.Timestamp): - The timestamp of when the build started. - build_finished_on (google.protobuf.timestamp_pb2.Timestamp): - The timestamp of when the build completed. - completeness (grafeas.grafeas_v1.types.SlsaProvenance.SlsaCompleteness): - Indicates that the builder claims certain - fields in this message to be complete. - reproducible (bool): - If true, the builder claims that running the - recipe on materials will produce bit-for-bit - identical output. - """ - - build_invocation_id: str = proto.Field( - proto.STRING, - number=1, - ) - build_started_on: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=2, - message=timestamp_pb2.Timestamp, - ) - build_finished_on: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=3, - message=timestamp_pb2.Timestamp, - ) - completeness: 'SlsaProvenance.SlsaCompleteness' = proto.Field( - proto.MESSAGE, - number=4, - message='SlsaProvenance.SlsaCompleteness', - ) - reproducible: bool = proto.Field( - proto.BOOL, - number=5, - ) - - class SlsaBuilder(proto.Message): - r""" - - Attributes: - id (str): - - """ - - id: str = proto.Field( - proto.STRING, - number=1, - ) - - class Material(proto.Message): - r""" - - Attributes: - uri (str): - - digest (MutableMapping[str, str]): - - """ - - uri: str = proto.Field( - proto.STRING, - number=1, - ) - digest: MutableMapping[str, str] = proto.MapField( - proto.STRING, - proto.STRING, - number=2, - ) - - builder: SlsaBuilder = proto.Field( - proto.MESSAGE, - number=1, - message=SlsaBuilder, - ) - recipe: SlsaRecipe = proto.Field( - proto.MESSAGE, - number=2, - message=SlsaRecipe, - ) - metadata: SlsaMetadata = proto.Field( - proto.MESSAGE, - number=3, - message=SlsaMetadata, - ) - materials: MutableSequence[Material] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message=Material, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance_zero_two.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance_zero_two.py deleted file mode 100644 index c7bb72971913..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/slsa_provenance_zero_two.py +++ /dev/null @@ -1,242 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 struct_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'SlsaProvenanceZeroTwo', - }, -) - - -class SlsaProvenanceZeroTwo(proto.Message): - r"""See full explanation of fields at slsa.dev/provenance/v0.2. - - Attributes: - builder (grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo.SlsaBuilder): - - build_type (str): - - invocation (grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo.SlsaInvocation): - - build_config (google.protobuf.struct_pb2.Struct): - - metadata (grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo.SlsaMetadata): - - materials (MutableSequence[grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo.SlsaMaterial]): - - """ - - class SlsaBuilder(proto.Message): - r"""Identifies the entity that executed the recipe, which is - trusted to have correctly performed the operation and populated - this provenance. - - Attributes: - id (str): - - """ - - id: str = proto.Field( - proto.STRING, - number=1, - ) - - class SlsaMaterial(proto.Message): - r"""The collection of artifacts that influenced the build - including sources, dependencies, build tools, base images, and - so on. - - Attributes: - uri (str): - - digest (MutableMapping[str, str]): - - """ - - uri: str = proto.Field( - proto.STRING, - number=1, - ) - digest: MutableMapping[str, str] = proto.MapField( - proto.STRING, - proto.STRING, - number=2, - ) - - class SlsaInvocation(proto.Message): - r"""Identifies the event that kicked off the build. - - Attributes: - config_source (grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo.SlsaConfigSource): - - parameters (google.protobuf.struct_pb2.Struct): - - environment (google.protobuf.struct_pb2.Struct): - - """ - - config_source: 'SlsaProvenanceZeroTwo.SlsaConfigSource' = proto.Field( - proto.MESSAGE, - number=1, - message='SlsaProvenanceZeroTwo.SlsaConfigSource', - ) - parameters: struct_pb2.Struct = proto.Field( - proto.MESSAGE, - number=2, - message=struct_pb2.Struct, - ) - environment: struct_pb2.Struct = proto.Field( - proto.MESSAGE, - number=3, - message=struct_pb2.Struct, - ) - - class SlsaConfigSource(proto.Message): - r"""Describes where the config file that kicked off the build - came from. This is effectively a pointer to the source where - buildConfig came from. - - Attributes: - uri (str): - - digest (MutableMapping[str, str]): - - entry_point (str): - - """ - - uri: str = proto.Field( - proto.STRING, - number=1, - ) - digest: MutableMapping[str, str] = proto.MapField( - proto.STRING, - proto.STRING, - number=2, - ) - entry_point: str = proto.Field( - proto.STRING, - number=3, - ) - - class SlsaMetadata(proto.Message): - r"""Other properties of the build. - - Attributes: - build_invocation_id (str): - - build_started_on (google.protobuf.timestamp_pb2.Timestamp): - - build_finished_on (google.protobuf.timestamp_pb2.Timestamp): - - completeness (grafeas.grafeas_v1.types.SlsaProvenanceZeroTwo.SlsaCompleteness): - - reproducible (bool): - - """ - - build_invocation_id: str = proto.Field( - proto.STRING, - number=1, - ) - build_started_on: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=2, - message=timestamp_pb2.Timestamp, - ) - build_finished_on: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=3, - message=timestamp_pb2.Timestamp, - ) - completeness: 'SlsaProvenanceZeroTwo.SlsaCompleteness' = proto.Field( - proto.MESSAGE, - number=4, - message='SlsaProvenanceZeroTwo.SlsaCompleteness', - ) - reproducible: bool = proto.Field( - proto.BOOL, - number=5, - ) - - class SlsaCompleteness(proto.Message): - r"""Indicates that the builder claims certain fields in this - message to be complete. - - Attributes: - parameters (bool): - - environment (bool): - - materials (bool): - - """ - - parameters: bool = proto.Field( - proto.BOOL, - number=1, - ) - environment: bool = proto.Field( - proto.BOOL, - number=2, - ) - materials: bool = proto.Field( - proto.BOOL, - number=3, - ) - - builder: SlsaBuilder = proto.Field( - proto.MESSAGE, - number=1, - message=SlsaBuilder, - ) - build_type: str = proto.Field( - proto.STRING, - number=2, - ) - invocation: SlsaInvocation = proto.Field( - proto.MESSAGE, - number=3, - message=SlsaInvocation, - ) - build_config: struct_pb2.Struct = proto.Field( - proto.MESSAGE, - number=4, - message=struct_pb2.Struct, - ) - metadata: SlsaMetadata = proto.Field( - proto.MESSAGE, - number=5, - message=SlsaMetadata, - ) - materials: MutableSequence[SlsaMaterial] = proto.RepeatedField( - proto.MESSAGE, - number=6, - message=SlsaMaterial, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/upgrade.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/upgrade.py deleted file mode 100644 index a7181f7a083f..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/upgrade.py +++ /dev/null @@ -1,266 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import package as g_package - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'UpgradeNote', - 'UpgradeDistribution', - 'WindowsUpdate', - 'UpgradeOccurrence', - }, -) - - -class UpgradeNote(proto.Message): - r"""An Upgrade Note represents a potential upgrade of a package to a - given version. For each package version combination (i.e. bash 4.0, - bash 4.1, bash 4.1.2), there will be an Upgrade Note. For Windows, - windows_update field represents the information related to the - update. - - Attributes: - package (str): - Required for non-Windows OS. The package this - Upgrade is for. - version (grafeas.grafeas_v1.types.Version): - Required for non-Windows OS. The version of - the package in machine + human readable form. - distributions (MutableSequence[grafeas.grafeas_v1.types.UpgradeDistribution]): - Metadata about the upgrade for each specific - operating system. - windows_update (grafeas.grafeas_v1.types.WindowsUpdate): - Required for Windows OS. Represents the - metadata about the Windows update. - """ - - package: str = proto.Field( - proto.STRING, - number=1, - ) - version: g_package.Version = proto.Field( - proto.MESSAGE, - number=2, - message=g_package.Version, - ) - distributions: MutableSequence['UpgradeDistribution'] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message='UpgradeDistribution', - ) - windows_update: 'WindowsUpdate' = proto.Field( - proto.MESSAGE, - number=4, - message='WindowsUpdate', - ) - - -class UpgradeDistribution(proto.Message): - r"""The Upgrade Distribution represents metadata about the - Upgrade for each operating system (CPE). Some distributions have - additional metadata around updates, classifying them into - various categories and severities. - - Attributes: - cpe_uri (str): - Required - The specific operating system this - metadata applies to. See - https://cpe.mitre.org/specification/. - classification (str): - The operating system classification of this Upgrade, as - specified by the upstream operating system upgrade feed. For - Windows the classification is one of the category_ids listed - at - https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ff357803(v=vs.85) - severity (str): - The severity as specified by the upstream - operating system. - cve (MutableSequence[str]): - The cve tied to this Upgrade. - """ - - cpe_uri: str = proto.Field( - proto.STRING, - number=1, - ) - classification: str = proto.Field( - proto.STRING, - number=2, - ) - severity: str = proto.Field( - proto.STRING, - number=3, - ) - cve: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=4, - ) - - -class WindowsUpdate(proto.Message): - r"""Windows Update represents the metadata about the update for - the Windows operating system. The fields in this message come - from the Windows Update API documented at - https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdate. - - Attributes: - identity (grafeas.grafeas_v1.types.WindowsUpdate.Identity): - Required - The unique identifier for the - update. - title (str): - The localized title of the update. - description (str): - The localized description of the update. - categories (MutableSequence[grafeas.grafeas_v1.types.WindowsUpdate.Category]): - The list of categories to which the update - belongs. - kb_article_ids (MutableSequence[str]): - The Microsoft Knowledge Base article IDs that - are associated with the update. - support_url (str): - The hyperlink to the support information for - the update. - last_published_timestamp (google.protobuf.timestamp_pb2.Timestamp): - The last published timestamp of the update. - """ - - class Identity(proto.Message): - r"""The unique identifier of the update. - - Attributes: - update_id (str): - The revision independent identifier of the - update. - revision (int): - The revision number of the update. - """ - - update_id: str = proto.Field( - proto.STRING, - number=1, - ) - revision: int = proto.Field( - proto.INT32, - number=2, - ) - - class Category(proto.Message): - r"""The category to which the update belongs. - - Attributes: - category_id (str): - The identifier of the category. - name (str): - The localized name of the category. - """ - - category_id: str = proto.Field( - proto.STRING, - number=1, - ) - name: str = proto.Field( - proto.STRING, - number=2, - ) - - identity: Identity = proto.Field( - proto.MESSAGE, - number=1, - message=Identity, - ) - title: str = proto.Field( - proto.STRING, - number=2, - ) - description: str = proto.Field( - proto.STRING, - number=3, - ) - categories: MutableSequence[Category] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message=Category, - ) - kb_article_ids: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=5, - ) - support_url: str = proto.Field( - proto.STRING, - number=6, - ) - last_published_timestamp: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=7, - message=timestamp_pb2.Timestamp, - ) - - -class UpgradeOccurrence(proto.Message): - r"""An Upgrade Occurrence represents that a specific resource_url could - install a specific upgrade. This presence is supplied via local - sources (i.e. it is present in the mirror and the running system has - noticed its availability). For Windows, both distribution and - windows_update contain information for the Windows update. - - Attributes: - package (str): - Required for non-Windows OS. The package this - Upgrade is for. - parsed_version (grafeas.grafeas_v1.types.Version): - Required for non-Windows OS. The version of - the package in a machine + human readable form. - distribution (grafeas.grafeas_v1.types.UpgradeDistribution): - Metadata about the upgrade for available for the specific - operating system for the resource_url. This allows efficient - filtering, as well as making it easier to use the - occurrence. - windows_update (grafeas.grafeas_v1.types.WindowsUpdate): - Required for Windows OS. Represents the - metadata about the Windows update. - """ - - package: str = proto.Field( - proto.STRING, - number=1, - ) - parsed_version: g_package.Version = proto.Field( - proto.MESSAGE, - number=3, - message=g_package.Version, - ) - distribution: 'UpgradeDistribution' = proto.Field( - proto.MESSAGE, - number=4, - message='UpgradeDistribution', - ) - windows_update: 'WindowsUpdate' = proto.Field( - proto.MESSAGE, - number=5, - message='WindowsUpdate', - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vex.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vex.py deleted file mode 100644 index 813c1613f2b7..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vex.py +++ /dev/null @@ -1,384 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import common - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'VulnerabilityAssessmentNote', - }, -) - - -class VulnerabilityAssessmentNote(proto.Message): - r"""A single VulnerabilityAssessmentNote represents - one particular product's vulnerability assessment for one CVE. - - Attributes: - title (str): - The title of the note. E.g. ``Vex-Debian-11.4`` - short_description (str): - A one sentence description of this Vex. - long_description (str): - A detailed description of this Vex. - language_code (str): - Identifies the language used by this - document, corresponding to IETF BCP 47 / RFC - 5646. - publisher (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Publisher): - Publisher details of this Note. - product (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Product): - The product affected by this vex. - assessment (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment): - Represents a vulnerability assessment for the - product. - """ - - class Publisher(proto.Message): - r"""Publisher contains information about the publisher of - this Note. - (-- api-linter: core::0123::resource-annotation=disabled - aip.dev/not-precedent: Publisher is not a separate resource. --) - - Attributes: - name (str): - Name of the publisher. - Examples: 'Google', 'Google Cloud Platform'. - issuing_authority (str): - Provides information about the authority of - the issuing party to release the document, in - particular, the party's constituency and - responsibilities or other obligations. - publisher_namespace (str): - The context or namespace. - Contains a URL which is under control of the - issuing party and can be used as a globally - unique identifier for that issuing party. - Example: https://csaf.io - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - issuing_authority: str = proto.Field( - proto.STRING, - number=2, - ) - publisher_namespace: str = proto.Field( - proto.STRING, - number=3, - ) - - class Product(proto.Message): - r"""Product contains information about a product and how to - uniquely identify it. - (-- api-linter: core::0123::resource-annotation=disabled - aip.dev/not-precedent: Product is not a separate resource. --) - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - name (str): - Name of the product. - id (str): - Token that identifies a product so that it - can be referred to from other parts in the - document. There is no predefined format as long - as it uniquely identifies a group in the context - of the current document. - generic_uri (str): - Contains a URI which is vendor-specific. - Example: The artifact repository URL of an - image. - - This field is a member of `oneof`_ ``identifier``. - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - id: str = proto.Field( - proto.STRING, - number=2, - ) - generic_uri: str = proto.Field( - proto.STRING, - number=3, - oneof='identifier', - ) - - class Assessment(proto.Message): - r"""Assessment provides all information that is related to a - single vulnerability for this product. - - Attributes: - cve (str): - Holds the MITRE standard Common Vulnerabilities and - Exposures (CVE) tracking number for the vulnerability. - Deprecated: Use vulnerability_id instead to denote CVEs. - vulnerability_id (str): - The vulnerability identifier for this - Assessment. Will hold one of common identifiers - e.g. CVE, GHSA etc. - short_description (str): - A one sentence description of this Vex. - long_description (str): - A detailed description of this Vex. - related_uris (MutableSequence[grafeas.grafeas_v1.types.RelatedUrl]): - Holds a list of references associated with - this vulnerability item and assessment. These - uris have additional information about the - vulnerability and the assessment itself. E.g. - Link to a document which details how this - assessment concluded the state of this - vulnerability. - state (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.State): - Provides the state of this Vulnerability - assessment. - impacts (MutableSequence[str]): - Contains information about the impact of this - vulnerability, this will change with time. - justification (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Justification): - Justification provides the justification when the state of - the assessment if NOT_AFFECTED. - remediations (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Remediation]): - Specifies details on how to handle (and - presumably, fix) a vulnerability. - """ - class State(proto.Enum): - r"""Provides the state of this Vulnerability assessment. - - Values: - STATE_UNSPECIFIED (0): - No state is specified. - AFFECTED (1): - This product is known to be affected by this - vulnerability. - NOT_AFFECTED (2): - This product is known to be not affected by - this vulnerability. - FIXED (3): - This product contains a fix for this - vulnerability. - UNDER_INVESTIGATION (4): - It is not known yet whether these versions - are or are not affected by the vulnerability. - However, it is still under investigation. - """ - STATE_UNSPECIFIED = 0 - AFFECTED = 1 - NOT_AFFECTED = 2 - FIXED = 3 - UNDER_INVESTIGATION = 4 - - class Justification(proto.Message): - r"""Justification provides the justification when the state of the - assessment if NOT_AFFECTED. - - Attributes: - justification_type (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Justification.JustificationType): - The justification type for this - vulnerability. - details (str): - Additional details on why this justification - was chosen. - """ - class JustificationType(proto.Enum): - r"""Provides the type of justification. - - Values: - JUSTIFICATION_TYPE_UNSPECIFIED (0): - JUSTIFICATION_TYPE_UNSPECIFIED. - COMPONENT_NOT_PRESENT (1): - The vulnerable component is not present in - the product. - VULNERABLE_CODE_NOT_PRESENT (2): - The vulnerable code is not present. Typically - this case occurs when source code is configured - or built in a way that excludes the vulnerable - code. - VULNERABLE_CODE_NOT_IN_EXECUTE_PATH (3): - The vulnerable code can not be executed. - Typically this case occurs when the product - includes the vulnerable code but does not call - or use the vulnerable code. - VULNERABLE_CODE_CANNOT_BE_CONTROLLED_BY_ADVERSARY (4): - The vulnerable code cannot be controlled by - an attacker to exploit the vulnerability. - INLINE_MITIGATIONS_ALREADY_EXIST (5): - The product includes built-in protections or - features that prevent exploitation of the - vulnerability. These built-in protections cannot - be subverted by the attacker and cannot be - configured or disabled by the user. These - mitigations completely prevent exploitation - based on known attack vectors. - """ - JUSTIFICATION_TYPE_UNSPECIFIED = 0 - COMPONENT_NOT_PRESENT = 1 - VULNERABLE_CODE_NOT_PRESENT = 2 - VULNERABLE_CODE_NOT_IN_EXECUTE_PATH = 3 - VULNERABLE_CODE_CANNOT_BE_CONTROLLED_BY_ADVERSARY = 4 - INLINE_MITIGATIONS_ALREADY_EXIST = 5 - - justification_type: 'VulnerabilityAssessmentNote.Assessment.Justification.JustificationType' = proto.Field( - proto.ENUM, - number=1, - enum='VulnerabilityAssessmentNote.Assessment.Justification.JustificationType', - ) - details: str = proto.Field( - proto.STRING, - number=2, - ) - - class Remediation(proto.Message): - r"""Specifies details on how to handle (and presumably, fix) a - vulnerability. - - Attributes: - remediation_type (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Remediation.RemediationType): - The type of remediation that can be applied. - details (str): - Contains a comprehensive human-readable - discussion of the remediation. - remediation_uri (grafeas.grafeas_v1.types.RelatedUrl): - Contains the URL where to obtain the - remediation. - """ - class RemediationType(proto.Enum): - r"""The type of remediation that can be applied. - - Values: - REMEDIATION_TYPE_UNSPECIFIED (0): - No remediation type specified. - MITIGATION (1): - A MITIGATION is available. - NO_FIX_PLANNED (2): - No fix is planned. - NONE_AVAILABLE (3): - Not available. - VENDOR_FIX (4): - A vendor fix is available. - WORKAROUND (5): - A workaround is available. - """ - REMEDIATION_TYPE_UNSPECIFIED = 0 - MITIGATION = 1 - NO_FIX_PLANNED = 2 - NONE_AVAILABLE = 3 - VENDOR_FIX = 4 - WORKAROUND = 5 - - remediation_type: 'VulnerabilityAssessmentNote.Assessment.Remediation.RemediationType' = proto.Field( - proto.ENUM, - number=1, - enum='VulnerabilityAssessmentNote.Assessment.Remediation.RemediationType', - ) - details: str = proto.Field( - proto.STRING, - number=2, - ) - remediation_uri: common.RelatedUrl = proto.Field( - proto.MESSAGE, - number=3, - message=common.RelatedUrl, - ) - - cve: str = proto.Field( - proto.STRING, - number=1, - ) - vulnerability_id: str = proto.Field( - proto.STRING, - number=9, - ) - short_description: str = proto.Field( - proto.STRING, - number=2, - ) - long_description: str = proto.Field( - proto.STRING, - number=3, - ) - related_uris: MutableSequence[common.RelatedUrl] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message=common.RelatedUrl, - ) - state: 'VulnerabilityAssessmentNote.Assessment.State' = proto.Field( - proto.ENUM, - number=5, - enum='VulnerabilityAssessmentNote.Assessment.State', - ) - impacts: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=6, - ) - justification: 'VulnerabilityAssessmentNote.Assessment.Justification' = proto.Field( - proto.MESSAGE, - number=7, - message='VulnerabilityAssessmentNote.Assessment.Justification', - ) - remediations: MutableSequence['VulnerabilityAssessmentNote.Assessment.Remediation'] = proto.RepeatedField( - proto.MESSAGE, - number=8, - message='VulnerabilityAssessmentNote.Assessment.Remediation', - ) - - title: str = proto.Field( - proto.STRING, - number=1, - ) - short_description: str = proto.Field( - proto.STRING, - number=2, - ) - long_description: str = proto.Field( - proto.STRING, - number=3, - ) - language_code: str = proto.Field( - proto.STRING, - number=4, - ) - publisher: Publisher = proto.Field( - proto.MESSAGE, - number=5, - message=Publisher, - ) - product: Product = proto.Field( - proto.MESSAGE, - number=6, - message=Product, - ) - assessment: Assessment = proto.Field( - proto.MESSAGE, - number=7, - message=Assessment, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vulnerability.py b/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vulnerability.py deleted file mode 100644 index 97000d7d501b..000000000000 --- a/owl-bot-staging/grafeas/v1/grafeas/grafeas_v1/types/vulnerability.py +++ /dev/null @@ -1,594 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES 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 grafeas.grafeas_v1.types import common -from grafeas.grafeas_v1.types import cvss -from grafeas.grafeas_v1.types import package -from grafeas.grafeas_v1.types import severity as g_severity -from grafeas.grafeas_v1.types import vex - - -__protobuf__ = proto.module( - package='grafeas.v1', - manifest={ - 'VulnerabilityNote', - 'VulnerabilityOccurrence', - }, -) - - -class VulnerabilityNote(proto.Message): - r"""A security vulnerability that can be found in resources. - - Attributes: - cvss_score (float): - The CVSS score of this vulnerability. CVSS - score is on a scale of 0 - 10 where 0 indicates - low severity and 10 indicates high severity. - severity (grafeas.grafeas_v1.types.Severity): - The note provider assigned severity of this - vulnerability. - details (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityNote.Detail]): - Details of all known distros and packages - affected by this vulnerability. - cvss_v3 (grafeas.grafeas_v1.types.CVSSv3): - The full description of the CVSSv3 for this - vulnerability. - windows_details (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityNote.WindowsDetail]): - Windows details get their own format because - the information format and model don't match a - normal detail. Specifically Windows updates are - done as patches, thus Windows vulnerabilities - really are a missing package, rather than a - package being at an incorrect version. - source_update_time (google.protobuf.timestamp_pb2.Timestamp): - The time this information was last changed at - the source. This is an upstream timestamp from - the underlying information source - e.g. Ubuntu - security tracker. - cvss_version (grafeas.grafeas_v1.types.CVSSVersion): - CVSS version used to populate cvss_score and severity. - cvss_v2 (grafeas.grafeas_v1.types.CVSS): - The full description of the v2 CVSS for this - vulnerability. - """ - - class Detail(proto.Message): - r"""A detail for a distro and package affected by this - vulnerability and its associated fix (if one is available). - - Attributes: - severity_name (str): - The distro assigned severity of this - vulnerability. - description (str): - A vendor-specific description of this - vulnerability. - package_type (str): - The type of package; whether native or non - native (e.g., ruby gems, node.js packages, - etc.). - affected_cpe_uri (str): - Required. The `CPE - URI `__ this - vulnerability affects. - affected_package (str): - Required. The package this vulnerability - affects. - affected_version_start (grafeas.grafeas_v1.types.Version): - The version number at the start of an interval in which this - vulnerability exists. A vulnerability can affect a package - between version numbers that are disjoint sets of intervals - (example: [1.0.0-1.1.0], [2.4.6-2.4.8] and [4.5.6-4.6.8]) - each of which will be represented in its own Detail. If a - specific affected version is provided by a vulnerability - database, affected_version_start and affected_version_end - will be the same in that Detail. - affected_version_end (grafeas.grafeas_v1.types.Version): - The version number at the end of an interval in which this - vulnerability exists. A vulnerability can affect a package - between version numbers that are disjoint sets of intervals - (example: [1.0.0-1.1.0], [2.4.6-2.4.8] and [4.5.6-4.6.8]) - each of which will be represented in its own Detail. If a - specific affected version is provided by a vulnerability - database, affected_version_start and affected_version_end - will be the same in that Detail. - fixed_cpe_uri (str): - The distro recommended `CPE - URI `__ to update to - that contains a fix for this vulnerability. It is possible - for this to be different from the affected_cpe_uri. - fixed_package (str): - The distro recommended package to update to that contains a - fix for this vulnerability. It is possible for this to be - different from the affected_package. - fixed_version (grafeas.grafeas_v1.types.Version): - The distro recommended version to update to - that contains a fix for this vulnerability. - Setting this to VersionKind.MAXIMUM means no - such version is yet available. - is_obsolete (bool): - Whether this detail is obsolete. Occurrences - are expected not to point to obsolete details. - source_update_time (google.protobuf.timestamp_pb2.Timestamp): - The time this information was last changed at - the source. This is an upstream timestamp from - the underlying information source - e.g. Ubuntu - security tracker. - source (str): - The source from which the information in this - Detail was obtained. - vendor (str): - The name of the vendor of the product. - """ - - severity_name: str = proto.Field( - proto.STRING, - number=1, - ) - description: str = proto.Field( - proto.STRING, - number=2, - ) - package_type: str = proto.Field( - proto.STRING, - number=3, - ) - affected_cpe_uri: str = proto.Field( - proto.STRING, - number=4, - ) - affected_package: str = proto.Field( - proto.STRING, - number=5, - ) - affected_version_start: package.Version = proto.Field( - proto.MESSAGE, - number=6, - message=package.Version, - ) - affected_version_end: package.Version = proto.Field( - proto.MESSAGE, - number=7, - message=package.Version, - ) - fixed_cpe_uri: str = proto.Field( - proto.STRING, - number=8, - ) - fixed_package: str = proto.Field( - proto.STRING, - number=9, - ) - fixed_version: package.Version = proto.Field( - proto.MESSAGE, - number=10, - message=package.Version, - ) - is_obsolete: bool = proto.Field( - proto.BOOL, - number=11, - ) - source_update_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=12, - message=timestamp_pb2.Timestamp, - ) - source: str = proto.Field( - proto.STRING, - number=13, - ) - vendor: str = proto.Field( - proto.STRING, - number=14, - ) - - class WindowsDetail(proto.Message): - r""" - - Attributes: - cpe_uri (str): - Required. The `CPE - URI `__ this - vulnerability affects. - name (str): - Required. The name of this vulnerability. - description (str): - The description of this vulnerability. - fixing_kbs (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityNote.WindowsDetail.KnowledgeBase]): - Required. The names of the KBs which have - hotfixes to mitigate this vulnerability. Note - that there may be multiple hotfixes (and thus - multiple KBs) that mitigate a given - vulnerability. Currently any listed KBs presence - is considered a fix. - """ - - class KnowledgeBase(proto.Message): - r""" - - Attributes: - name (str): - The KB name (generally of the form KB[0-9]+ (e.g., - KB123456)). - url (str): - A link to the KB in the [Windows update catalog] - (https://www.catalog.update.microsoft.com/). - """ - - name: str = proto.Field( - proto.STRING, - number=1, - ) - url: str = proto.Field( - proto.STRING, - number=2, - ) - - cpe_uri: str = proto.Field( - proto.STRING, - number=1, - ) - name: str = proto.Field( - proto.STRING, - number=2, - ) - description: str = proto.Field( - proto.STRING, - number=3, - ) - fixing_kbs: MutableSequence['VulnerabilityNote.WindowsDetail.KnowledgeBase'] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message='VulnerabilityNote.WindowsDetail.KnowledgeBase', - ) - - cvss_score: float = proto.Field( - proto.FLOAT, - number=1, - ) - severity: g_severity.Severity = proto.Field( - proto.ENUM, - number=2, - enum=g_severity.Severity, - ) - details: MutableSequence[Detail] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message=Detail, - ) - cvss_v3: cvss.CVSSv3 = proto.Field( - proto.MESSAGE, - number=4, - message=cvss.CVSSv3, - ) - windows_details: MutableSequence[WindowsDetail] = proto.RepeatedField( - proto.MESSAGE, - number=5, - message=WindowsDetail, - ) - source_update_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=6, - message=timestamp_pb2.Timestamp, - ) - cvss_version: cvss.CVSSVersion = proto.Field( - proto.ENUM, - number=7, - enum=cvss.CVSSVersion, - ) - cvss_v2: cvss.CVSS = proto.Field( - proto.MESSAGE, - number=8, - message=cvss.CVSS, - ) - - -class VulnerabilityOccurrence(proto.Message): - r"""An occurrence of a severity vulnerability on a resource. - - Attributes: - type_ (str): - The type of package; whether native or non - native (e.g., ruby gems, node.js packages, - etc.). - severity (grafeas.grafeas_v1.types.Severity): - Output only. The note provider assigned - severity of this vulnerability. - cvss_score (float): - Output only. The CVSS score of this - vulnerability. CVSS score is on a scale of 0 - - 10 where 0 indicates low severity and 10 - indicates high severity. - cvssv3 (grafeas.grafeas_v1.types.CVSS): - The cvss v3 score for the vulnerability. - package_issue (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityOccurrence.PackageIssue]): - Required. The set of affected locations and - their fixes (if available) within the associated - resource. - short_description (str): - Output only. A one sentence description of - this vulnerability. - long_description (str): - Output only. A detailed description of this - vulnerability. - related_urls (MutableSequence[grafeas.grafeas_v1.types.RelatedUrl]): - Output only. URLs related to this - vulnerability. - effective_severity (grafeas.grafeas_v1.types.Severity): - The distro assigned severity for this - vulnerability when it is available, otherwise - this is the note provider assigned severity. - - When there are multiple PackageIssues for this - vulnerability, they can have different effective - severities because some might be provided by the - distro while others are provided by the language - ecosystem for a language pack. For this reason, - it is advised to use the effective severity on - the PackageIssue level. In the case where - multiple PackageIssues have differing effective - severities, this field should be the highest - severity for any of the PackageIssues. - fix_available (bool): - Output only. Whether at least one of the - affected packages has a fix available. - cvss_version (grafeas.grafeas_v1.types.CVSSVersion): - Output only. CVSS version used to populate cvss_score and - severity. - cvss_v2 (grafeas.grafeas_v1.types.CVSS): - The cvss v2 score for the vulnerability. - vex_assessment (grafeas.grafeas_v1.types.VulnerabilityOccurrence.VexAssessment): - - extra_details (str): - Occurrence-specific extra details about the - vulnerability. - """ - - class PackageIssue(proto.Message): - r"""A detail for a distro and package this vulnerability - occurrence was found in and its associated fix (if one is - available). - - Attributes: - affected_cpe_uri (str): - Required. The `CPE - URI `__ this - vulnerability was found in. - affected_package (str): - Required. The package this vulnerability was - found in. - affected_version (grafeas.grafeas_v1.types.Version): - Required. The version of the package that is - installed on the resource affected by this - vulnerability. - fixed_cpe_uri (str): - The `CPE URI `__ this - vulnerability was fixed in. It is possible for this to be - different from the affected_cpe_uri. - fixed_package (str): - The package this vulnerability was fixed in. It is possible - for this to be different from the affected_package. - fixed_version (grafeas.grafeas_v1.types.Version): - Required. The version of the package this - vulnerability was fixed in. Setting this to - VersionKind.MAXIMUM means no fix is yet - available. - fix_available (bool): - Output only. Whether a fix is available for - this package. - package_type (str): - The type of package (e.g. OS, MAVEN, GO). - effective_severity (grafeas.grafeas_v1.types.Severity): - The distro or language system assigned - severity for this vulnerability when that is - available and note provider assigned severity - when it is not available. - file_location (MutableSequence[grafeas.grafeas_v1.types.FileLocation]): - The location at which this package was found. - """ - - affected_cpe_uri: str = proto.Field( - proto.STRING, - number=1, - ) - affected_package: str = proto.Field( - proto.STRING, - number=2, - ) - affected_version: package.Version = proto.Field( - proto.MESSAGE, - number=3, - message=package.Version, - ) - fixed_cpe_uri: str = proto.Field( - proto.STRING, - number=4, - ) - fixed_package: str = proto.Field( - proto.STRING, - number=5, - ) - fixed_version: package.Version = proto.Field( - proto.MESSAGE, - number=6, - message=package.Version, - ) - fix_available: bool = proto.Field( - proto.BOOL, - number=7, - ) - package_type: str = proto.Field( - proto.STRING, - number=8, - ) - effective_severity: g_severity.Severity = proto.Field( - proto.ENUM, - number=9, - enum=g_severity.Severity, - ) - file_location: MutableSequence[common.FileLocation] = proto.RepeatedField( - proto.MESSAGE, - number=10, - message=common.FileLocation, - ) - - class VexAssessment(proto.Message): - r"""VexAssessment provides all publisher provided Vex information - that is related to this vulnerability. - - Attributes: - cve (str): - Holds the MITRE standard Common Vulnerabilities and - Exposures (CVE) tracking number for the vulnerability. - Deprecated: Use vulnerability_id instead to denote CVEs. - vulnerability_id (str): - The vulnerability identifier for this - Assessment. Will hold one of common identifiers - e.g. CVE, GHSA etc. - related_uris (MutableSequence[grafeas.grafeas_v1.types.RelatedUrl]): - Holds a list of references associated with - this vulnerability item and assessment. - note_name (str): - The VulnerabilityAssessment note from which this - VexAssessment was generated. This will be of the form: - ``projects/[PROJECT_ID]/notes/[NOTE_ID]``. (-- api-linter: - core::0122::name-suffix=disabled aip.dev/not-precedent: The - suffix is kept for consistency. --) - state (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.State): - Provides the state of this Vulnerability - assessment. - impacts (MutableSequence[str]): - Contains information about the impact of this - vulnerability, this will change with time. - remediations (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Remediation]): - Specifies details on how to handle (and - presumably, fix) a vulnerability. - justification (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Justification): - Justification provides the justification when the state of - the assessment if NOT_AFFECTED. - """ - - cve: str = proto.Field( - proto.STRING, - number=1, - ) - vulnerability_id: str = proto.Field( - proto.STRING, - number=8, - ) - related_uris: MutableSequence[common.RelatedUrl] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message=common.RelatedUrl, - ) - note_name: str = proto.Field( - proto.STRING, - number=3, - ) - state: vex.VulnerabilityAssessmentNote.Assessment.State = proto.Field( - proto.ENUM, - number=4, - enum=vex.VulnerabilityAssessmentNote.Assessment.State, - ) - impacts: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=5, - ) - remediations: MutableSequence[vex.VulnerabilityAssessmentNote.Assessment.Remediation] = proto.RepeatedField( - proto.MESSAGE, - number=6, - message=vex.VulnerabilityAssessmentNote.Assessment.Remediation, - ) - justification: vex.VulnerabilityAssessmentNote.Assessment.Justification = proto.Field( - proto.MESSAGE, - number=7, - message=vex.VulnerabilityAssessmentNote.Assessment.Justification, - ) - - type_: str = proto.Field( - proto.STRING, - number=1, - ) - severity: g_severity.Severity = proto.Field( - proto.ENUM, - number=2, - enum=g_severity.Severity, - ) - cvss_score: float = proto.Field( - proto.FLOAT, - number=3, - ) - cvssv3: cvss.CVSS = proto.Field( - proto.MESSAGE, - number=10, - message=cvss.CVSS, - ) - package_issue: MutableSequence[PackageIssue] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message=PackageIssue, - ) - short_description: str = proto.Field( - proto.STRING, - number=5, - ) - long_description: str = proto.Field( - proto.STRING, - number=6, - ) - related_urls: MutableSequence[common.RelatedUrl] = proto.RepeatedField( - proto.MESSAGE, - number=7, - message=common.RelatedUrl, - ) - effective_severity: g_severity.Severity = proto.Field( - proto.ENUM, - number=8, - enum=g_severity.Severity, - ) - fix_available: bool = proto.Field( - proto.BOOL, - number=9, - ) - cvss_version: cvss.CVSSVersion = proto.Field( - proto.ENUM, - number=11, - enum=cvss.CVSSVersion, - ) - cvss_v2: cvss.CVSS = proto.Field( - proto.MESSAGE, - number=12, - message=cvss.CVSS, - ) - vex_assessment: VexAssessment = proto.Field( - proto.MESSAGE, - number=13, - message=VexAssessment, - ) - extra_details: str = proto.Field( - proto.STRING, - number=14, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/grafeas/v1/mypy.ini b/owl-bot-staging/grafeas/v1/mypy.ini deleted file mode 100644 index 574c5aed394b..000000000000 --- a/owl-bot-staging/grafeas/v1/mypy.ini +++ /dev/null @@ -1,3 +0,0 @@ -[mypy] -python_version = 3.7 -namespace_packages = True diff --git a/owl-bot-staging/grafeas/v1/noxfile.py b/owl-bot-staging/grafeas/v1/noxfile.py deleted file mode 100644 index 72c4db956057..000000000000 --- a/owl-bot-staging/grafeas/v1/noxfile.py +++ /dev/null @@ -1,280 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 re -import shutil -import subprocess -import sys - - -import nox # type: ignore - -ALL_PYTHON = [ - "3.7", - "3.8", - "3.9", - "3.10", - "3.11", - "3.12", - "3.13", -] - -CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() - -LOWER_BOUND_CONSTRAINTS_FILE = CURRENT_DIRECTORY / "constraints.txt" -PACKAGE_NAME = 'grafeas' - -BLACK_VERSION = "black==22.3.0" -BLACK_PATHS = ["docs", "google", "tests", "samples", "noxfile.py", "setup.py"] -DEFAULT_PYTHON_VERSION = "3.13" - -nox.sessions = [ - "unit", - "cover", - "mypy", - "check_lower_bounds" - # exclude update_lower_bounds from default - "docs", - "blacken", - "lint", - "prerelease_deps", -] - -@nox.session(python=ALL_PYTHON) -@nox.parametrize( - "protobuf_implementation", - [ "python", "upb", "cpp" ], -) -def unit(session, protobuf_implementation): - """Run the unit test suite.""" - - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): - session.skip("cpp implementation is not supported in python 3.11+") - - session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') - session.install('-e', '.', "-c", f"testing/constraints-{session.python}.txt") - - # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. - # The 'cpp' implementation requires Protobuf<4. - if protobuf_implementation == "cpp": - session.install("protobuf<4") - - session.run( - 'py.test', - '--quiet', - '--cov=grafeas/grafeas_v1/', - '--cov=tests/', - '--cov-config=.coveragerc', - '--cov-report=term', - '--cov-report=html', - os.path.join('tests', 'unit', ''.join(session.posargs)), - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - -@nox.session(python=ALL_PYTHON[-1]) -@nox.parametrize( - "protobuf_implementation", - [ "python", "upb", "cpp" ], -) -def prerelease_deps(session, protobuf_implementation): - """Run the unit test suite against pre-release versions of dependencies.""" - - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): - session.skip("cpp implementation is not supported in python 3.11+") - - # Install test environment dependencies - session.install('coverage', 'pytest', 'pytest-cov', 'pytest-asyncio', 'asyncmock; python_version < "3.8"') - - # Install the package without dependencies - session.install('-e', '.', '--no-deps') - - # We test the minimum dependency versions using the minimum Python - # version so the lowest python runtime that we test has a corresponding constraints - # file, located at `testing/constraints--.txt`, which contains all of the - # dependencies and extras. - with open( - CURRENT_DIRECTORY - / "testing" - / f"constraints-{ALL_PYTHON[0]}.txt", - encoding="utf-8", - ) as constraints_file: - constraints_text = constraints_file.read() - - # Ignore leading whitespace and comment lines. - constraints_deps = [ - match.group(1) - for match in re.finditer( - r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE - ) - ] - - session.install(*constraints_deps) - - prerel_deps = [ - "googleapis-common-protos", - "google-api-core", - "google-auth", - # Exclude grpcio!=1.67.0rc1 which does not support python 3.13 - "grpcio!=1.67.0rc1", - "grpcio-status", - "protobuf", - "proto-plus", - ] - - for dep in prerel_deps: - session.install("--pre", "--no-deps", "--upgrade", dep) - - # Remaining dependencies - other_deps = [ - "requests", - ] - session.install(*other_deps) - - # Print out prerelease package versions - - session.run("python", "-c", "import google.api_core; print(google.api_core.__version__)") - session.run("python", "-c", "import google.auth; print(google.auth.__version__)") - session.run("python", "-c", "import grpc; print(grpc.__version__)") - session.run( - "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" - ) - session.run( - "python", "-c", "import proto; print(proto.__version__)" - ) - - session.run( - 'py.test', - '--quiet', - '--cov=grafeas/grafeas_v1/', - '--cov=tests/', - '--cov-config=.coveragerc', - '--cov-report=term', - '--cov-report=html', - os.path.join('tests', 'unit', ''.join(session.posargs)), - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - - -@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', - '-p', - 'grafeas', - ) - - -@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, - ) diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_async.py deleted file mode 100644 index 9ed3ef3bae74..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_async.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for BatchCreateNotes -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_BatchCreateNotes_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 grafeas import grafeas_v1 - - -async def sample_batch_create_notes(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.BatchCreateNotesRequest( - parent="parent_value", - ) - - # Make the request - response = await client.batch_create_notes(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_BatchCreateNotes_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_sync.py deleted file mode 100644 index 096f01fd138e..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_notes_sync.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for BatchCreateNotes -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_BatchCreateNotes_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 grafeas import grafeas_v1 - - -def sample_batch_create_notes(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.BatchCreateNotesRequest( - parent="parent_value", - ) - - # Make the request - response = client.batch_create_notes(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_BatchCreateNotes_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_async.py deleted file mode 100644 index 10d0a30d5906..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_async.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for BatchCreateOccurrences -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_BatchCreateOccurrences_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 grafeas import grafeas_v1 - - -async def sample_batch_create_occurrences(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.BatchCreateOccurrencesRequest( - parent="parent_value", - ) - - # Make the request - response = await client.batch_create_occurrences(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_BatchCreateOccurrences_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_sync.py deleted file mode 100644 index 8f3350d81758..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_batch_create_occurrences_sync.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for BatchCreateOccurrences -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_BatchCreateOccurrences_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 grafeas import grafeas_v1 - - -def sample_batch_create_occurrences(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.BatchCreateOccurrencesRequest( - parent="parent_value", - ) - - # Make the request - response = client.batch_create_occurrences(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_BatchCreateOccurrences_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_async.py deleted file mode 100644 index 22163012ecf9..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_async.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for CreateNote -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_CreateNote_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 grafeas import grafeas_v1 - - -async def sample_create_note(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.CreateNoteRequest( - parent="parent_value", - note_id="note_id_value", - ) - - # Make the request - response = await client.create_note(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_CreateNote_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_sync.py deleted file mode 100644 index 45d9b8827182..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_note_sync.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for CreateNote -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_CreateNote_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 grafeas import grafeas_v1 - - -def sample_create_note(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.CreateNoteRequest( - parent="parent_value", - note_id="note_id_value", - ) - - # Make the request - response = client.create_note(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_CreateNote_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_async.py deleted file mode 100644 index 55ad3999e351..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_async.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for CreateOccurrence -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_CreateOccurrence_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 grafeas import grafeas_v1 - - -async def sample_create_occurrence(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.CreateOccurrenceRequest( - parent="parent_value", - ) - - # Make the request - response = await client.create_occurrence(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_CreateOccurrence_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_sync.py deleted file mode 100644 index fbb4fd13a857..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_create_occurrence_sync.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for CreateOccurrence -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_CreateOccurrence_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 grafeas import grafeas_v1 - - -def sample_create_occurrence(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.CreateOccurrenceRequest( - parent="parent_value", - ) - - # Make the request - response = client.create_occurrence(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_CreateOccurrence_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_async.py deleted file mode 100644 index c128ae0f2a90..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_async.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for DeleteNote -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_DeleteNote_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 grafeas import grafeas_v1 - - -async def sample_delete_note(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.DeleteNoteRequest( - name="name_value", - ) - - # Make the request - await client.delete_note(request=request) - - -# [END containeranalysis_v1_generated_Grafeas_DeleteNote_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_sync.py deleted file mode 100644 index 8311e5af56c1..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_note_sync.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for DeleteNote -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_DeleteNote_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 grafeas import grafeas_v1 - - -def sample_delete_note(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.DeleteNoteRequest( - name="name_value", - ) - - # Make the request - client.delete_note(request=request) - - -# [END containeranalysis_v1_generated_Grafeas_DeleteNote_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_async.py deleted file mode 100644 index eb53c4ac9f81..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_async.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for DeleteOccurrence -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_DeleteOccurrence_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 grafeas import grafeas_v1 - - -async def sample_delete_occurrence(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.DeleteOccurrenceRequest( - name="name_value", - ) - - # Make the request - await client.delete_occurrence(request=request) - - -# [END containeranalysis_v1_generated_Grafeas_DeleteOccurrence_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_sync.py deleted file mode 100644 index 1d3df488a391..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_delete_occurrence_sync.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for DeleteOccurrence -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_DeleteOccurrence_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 grafeas import grafeas_v1 - - -def sample_delete_occurrence(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.DeleteOccurrenceRequest( - name="name_value", - ) - - # Make the request - client.delete_occurrence(request=request) - - -# [END containeranalysis_v1_generated_Grafeas_DeleteOccurrence_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_async.py deleted file mode 100644 index eb74332119ed..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_async.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for GetNote -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_GetNote_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 grafeas import grafeas_v1 - - -async def sample_get_note(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.GetNoteRequest( - name="name_value", - ) - - # Make the request - response = await client.get_note(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_GetNote_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_sync.py deleted file mode 100644 index 4026633cc025..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_note_sync.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for GetNote -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_GetNote_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 grafeas import grafeas_v1 - - -def sample_get_note(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.GetNoteRequest( - name="name_value", - ) - - # Make the request - response = client.get_note(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_GetNote_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_async.py deleted file mode 100644 index cedafd39e047..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_async.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for GetOccurrence -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_GetOccurrence_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 grafeas import grafeas_v1 - - -async def sample_get_occurrence(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.GetOccurrenceRequest( - name="name_value", - ) - - # Make the request - response = await client.get_occurrence(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_GetOccurrence_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_async.py deleted file mode 100644 index 28817551ddf3..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_async.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for GetOccurrenceNote -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_GetOccurrenceNote_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 grafeas import grafeas_v1 - - -async def sample_get_occurrence_note(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.GetOccurrenceNoteRequest( - name="name_value", - ) - - # Make the request - response = await client.get_occurrence_note(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_GetOccurrenceNote_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_sync.py deleted file mode 100644 index 7bf9619cccaf..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_note_sync.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for GetOccurrenceNote -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_GetOccurrenceNote_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 grafeas import grafeas_v1 - - -def sample_get_occurrence_note(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.GetOccurrenceNoteRequest( - name="name_value", - ) - - # Make the request - response = client.get_occurrence_note(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_GetOccurrenceNote_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_sync.py deleted file mode 100644 index 644d7b6f2049..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_get_occurrence_sync.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for GetOccurrence -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_GetOccurrence_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 grafeas import grafeas_v1 - - -def sample_get_occurrence(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.GetOccurrenceRequest( - name="name_value", - ) - - # Make the request - response = client.get_occurrence(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_GetOccurrence_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_async.py deleted file mode 100644 index ea4829680ae4..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_async.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListNoteOccurrences -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_ListNoteOccurrences_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 grafeas import grafeas_v1 - - -async def sample_list_note_occurrences(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.ListNoteOccurrencesRequest( - name="name_value", - ) - - # Make the request - page_result = client.list_note_occurrences(request=request) - - # Handle the response - async for response in page_result: - print(response) - -# [END containeranalysis_v1_generated_Grafeas_ListNoteOccurrences_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_sync.py deleted file mode 100644 index 789dcba080e8..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_note_occurrences_sync.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListNoteOccurrences -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_ListNoteOccurrences_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 grafeas import grafeas_v1 - - -def sample_list_note_occurrences(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.ListNoteOccurrencesRequest( - name="name_value", - ) - - # Make the request - page_result = client.list_note_occurrences(request=request) - - # Handle the response - for response in page_result: - print(response) - -# [END containeranalysis_v1_generated_Grafeas_ListNoteOccurrences_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_async.py deleted file mode 100644 index 488eb4dad8aa..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_async.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListNotes -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_ListNotes_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 grafeas import grafeas_v1 - - -async def sample_list_notes(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.ListNotesRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_notes(request=request) - - # Handle the response - async for response in page_result: - print(response) - -# [END containeranalysis_v1_generated_Grafeas_ListNotes_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_sync.py deleted file mode 100644 index d1ce09fe5d61..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_notes_sync.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListNotes -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_ListNotes_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 grafeas import grafeas_v1 - - -def sample_list_notes(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.ListNotesRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_notes(request=request) - - # Handle the response - for response in page_result: - print(response) - -# [END containeranalysis_v1_generated_Grafeas_ListNotes_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_async.py deleted file mode 100644 index 007d4ef85574..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_async.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListOccurrences -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_ListOccurrences_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 grafeas import grafeas_v1 - - -async def sample_list_occurrences(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.ListOccurrencesRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_occurrences(request=request) - - # Handle the response - async for response in page_result: - print(response) - -# [END containeranalysis_v1_generated_Grafeas_ListOccurrences_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_sync.py deleted file mode 100644 index d960929c9388..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_list_occurrences_sync.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListOccurrences -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_ListOccurrences_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 grafeas import grafeas_v1 - - -def sample_list_occurrences(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.ListOccurrencesRequest( - parent="parent_value", - ) - - # Make the request - page_result = client.list_occurrences(request=request) - - # Handle the response - for response in page_result: - print(response) - -# [END containeranalysis_v1_generated_Grafeas_ListOccurrences_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_async.py deleted file mode 100644 index 5a15196348e3..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_async.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for UpdateNote -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_UpdateNote_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 grafeas import grafeas_v1 - - -async def sample_update_note(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.UpdateNoteRequest( - name="name_value", - ) - - # Make the request - response = await client.update_note(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_UpdateNote_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_sync.py deleted file mode 100644 index ea0db334ebc1..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_note_sync.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for UpdateNote -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_UpdateNote_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 grafeas import grafeas_v1 - - -def sample_update_note(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.UpdateNoteRequest( - name="name_value", - ) - - # Make the request - response = client.update_note(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_UpdateNote_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_async.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_async.py deleted file mode 100644 index 38d13497f807..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_async.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for UpdateOccurrence -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_UpdateOccurrence_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 grafeas import grafeas_v1 - - -async def sample_update_occurrence(): - # Create a client - client = grafeas_v1.GrafeasAsyncClient() - - # Initialize request argument(s) - request = grafeas_v1.UpdateOccurrenceRequest( - name="name_value", - ) - - # Make the request - response = await client.update_occurrence(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_UpdateOccurrence_async] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_sync.py b/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_sync.py deleted file mode 100644 index af456757fbb8..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/containeranalysis_v1_generated_grafeas_update_occurrence_sync.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for UpdateOccurrence -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install grafeas - - -# [START containeranalysis_v1_generated_Grafeas_UpdateOccurrence_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 grafeas import grafeas_v1 - - -def sample_update_occurrence(): - # Create a client - client = grafeas_v1.GrafeasClient() - - # Initialize request argument(s) - request = grafeas_v1.UpdateOccurrenceRequest( - name="name_value", - ) - - # Make the request - response = client.update_occurrence(request=request) - - # Handle the response - print(response) - -# [END containeranalysis_v1_generated_Grafeas_UpdateOccurrence_sync] diff --git a/owl-bot-staging/grafeas/v1/samples/generated_samples/snippet_metadata_grafeas.v1.json b/owl-bot-staging/grafeas/v1/samples/generated_samples/snippet_metadata_grafeas.v1.json deleted file mode 100644 index dc3e1cc8b7ee..000000000000 --- a/owl-bot-staging/grafeas/v1/samples/generated_samples/snippet_metadata_grafeas.v1.json +++ /dev/null @@ -1,2353 +0,0 @@ -{ - "clientLibrary": { - "apis": [ - { - "id": "grafeas.v1", - "version": "v1" - } - ], - "language": "PYTHON", - "name": "grafeas", - "version": "0.1.0" - }, - "snippets": [ - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.batch_create_notes", - "method": { - "fullName": "grafeas.v1.Grafeas.BatchCreateNotes", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "BatchCreateNotes" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.BatchCreateNotesRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "notes", - "type": "MutableMapping[str, grafeas.grafeas_v1.types.Note]" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.BatchCreateNotesResponse", - "shortName": "batch_create_notes" - }, - "description": "Sample for BatchCreateNotes", - "file": "containeranalysis_v1_generated_grafeas_batch_create_notes_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_BatchCreateNotes_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": "containeranalysis_v1_generated_grafeas_batch_create_notes_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.batch_create_notes", - "method": { - "fullName": "grafeas.v1.Grafeas.BatchCreateNotes", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "BatchCreateNotes" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.BatchCreateNotesRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "notes", - "type": "MutableMapping[str, grafeas.grafeas_v1.types.Note]" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.BatchCreateNotesResponse", - "shortName": "batch_create_notes" - }, - "description": "Sample for BatchCreateNotes", - "file": "containeranalysis_v1_generated_grafeas_batch_create_notes_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_BatchCreateNotes_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": "containeranalysis_v1_generated_grafeas_batch_create_notes_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.batch_create_occurrences", - "method": { - "fullName": "grafeas.v1.Grafeas.BatchCreateOccurrences", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "BatchCreateOccurrences" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.BatchCreateOccurrencesRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "occurrences", - "type": "MutableSequence[grafeas.grafeas_v1.types.Occurrence]" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse", - "shortName": "batch_create_occurrences" - }, - "description": "Sample for BatchCreateOccurrences", - "file": "containeranalysis_v1_generated_grafeas_batch_create_occurrences_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_BatchCreateOccurrences_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": "containeranalysis_v1_generated_grafeas_batch_create_occurrences_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.batch_create_occurrences", - "method": { - "fullName": "grafeas.v1.Grafeas.BatchCreateOccurrences", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "BatchCreateOccurrences" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.BatchCreateOccurrencesRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "occurrences", - "type": "MutableSequence[grafeas.grafeas_v1.types.Occurrence]" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse", - "shortName": "batch_create_occurrences" - }, - "description": "Sample for BatchCreateOccurrences", - "file": "containeranalysis_v1_generated_grafeas_batch_create_occurrences_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_BatchCreateOccurrences_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": "containeranalysis_v1_generated_grafeas_batch_create_occurrences_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.create_note", - "method": { - "fullName": "grafeas.v1.Grafeas.CreateNote", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "CreateNote" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.CreateNoteRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "note_id", - "type": "str" - }, - { - "name": "note", - "type": "grafeas.grafeas_v1.types.Note" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.Note", - "shortName": "create_note" - }, - "description": "Sample for CreateNote", - "file": "containeranalysis_v1_generated_grafeas_create_note_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_CreateNote_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": "containeranalysis_v1_generated_grafeas_create_note_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.create_note", - "method": { - "fullName": "grafeas.v1.Grafeas.CreateNote", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "CreateNote" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.CreateNoteRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "note_id", - "type": "str" - }, - { - "name": "note", - "type": "grafeas.grafeas_v1.types.Note" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.Note", - "shortName": "create_note" - }, - "description": "Sample for CreateNote", - "file": "containeranalysis_v1_generated_grafeas_create_note_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_CreateNote_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": "containeranalysis_v1_generated_grafeas_create_note_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.create_occurrence", - "method": { - "fullName": "grafeas.v1.Grafeas.CreateOccurrence", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "CreateOccurrence" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.CreateOccurrenceRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "occurrence", - "type": "grafeas.grafeas_v1.types.Occurrence" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.Occurrence", - "shortName": "create_occurrence" - }, - "description": "Sample for CreateOccurrence", - "file": "containeranalysis_v1_generated_grafeas_create_occurrence_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_CreateOccurrence_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": "containeranalysis_v1_generated_grafeas_create_occurrence_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.create_occurrence", - "method": { - "fullName": "grafeas.v1.Grafeas.CreateOccurrence", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "CreateOccurrence" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.CreateOccurrenceRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "occurrence", - "type": "grafeas.grafeas_v1.types.Occurrence" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.Occurrence", - "shortName": "create_occurrence" - }, - "description": "Sample for CreateOccurrence", - "file": "containeranalysis_v1_generated_grafeas_create_occurrence_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_CreateOccurrence_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": "containeranalysis_v1_generated_grafeas_create_occurrence_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.delete_note", - "method": { - "fullName": "grafeas.v1.Grafeas.DeleteNote", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "DeleteNote" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.DeleteNoteRequest" - }, - { - "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_note" - }, - "description": "Sample for DeleteNote", - "file": "containeranalysis_v1_generated_grafeas_delete_note_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_DeleteNote_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": "containeranalysis_v1_generated_grafeas_delete_note_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.delete_note", - "method": { - "fullName": "grafeas.v1.Grafeas.DeleteNote", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "DeleteNote" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.DeleteNoteRequest" - }, - { - "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_note" - }, - "description": "Sample for DeleteNote", - "file": "containeranalysis_v1_generated_grafeas_delete_note_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_DeleteNote_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": "containeranalysis_v1_generated_grafeas_delete_note_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.delete_occurrence", - "method": { - "fullName": "grafeas.v1.Grafeas.DeleteOccurrence", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "DeleteOccurrence" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.DeleteOccurrenceRequest" - }, - { - "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_occurrence" - }, - "description": "Sample for DeleteOccurrence", - "file": "containeranalysis_v1_generated_grafeas_delete_occurrence_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_DeleteOccurrence_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": "containeranalysis_v1_generated_grafeas_delete_occurrence_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.delete_occurrence", - "method": { - "fullName": "grafeas.v1.Grafeas.DeleteOccurrence", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "DeleteOccurrence" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.DeleteOccurrenceRequest" - }, - { - "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_occurrence" - }, - "description": "Sample for DeleteOccurrence", - "file": "containeranalysis_v1_generated_grafeas_delete_occurrence_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_DeleteOccurrence_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": "containeranalysis_v1_generated_grafeas_delete_occurrence_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.get_note", - "method": { - "fullName": "grafeas.v1.Grafeas.GetNote", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "GetNote" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.GetNoteRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.Note", - "shortName": "get_note" - }, - "description": "Sample for GetNote", - "file": "containeranalysis_v1_generated_grafeas_get_note_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_GetNote_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": "containeranalysis_v1_generated_grafeas_get_note_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.get_note", - "method": { - "fullName": "grafeas.v1.Grafeas.GetNote", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "GetNote" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.GetNoteRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.Note", - "shortName": "get_note" - }, - "description": "Sample for GetNote", - "file": "containeranalysis_v1_generated_grafeas_get_note_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_GetNote_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": "containeranalysis_v1_generated_grafeas_get_note_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.get_occurrence_note", - "method": { - "fullName": "grafeas.v1.Grafeas.GetOccurrenceNote", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "GetOccurrenceNote" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.GetOccurrenceNoteRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.Note", - "shortName": "get_occurrence_note" - }, - "description": "Sample for GetOccurrenceNote", - "file": "containeranalysis_v1_generated_grafeas_get_occurrence_note_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_GetOccurrenceNote_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": "containeranalysis_v1_generated_grafeas_get_occurrence_note_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.get_occurrence_note", - "method": { - "fullName": "grafeas.v1.Grafeas.GetOccurrenceNote", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "GetOccurrenceNote" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.GetOccurrenceNoteRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.Note", - "shortName": "get_occurrence_note" - }, - "description": "Sample for GetOccurrenceNote", - "file": "containeranalysis_v1_generated_grafeas_get_occurrence_note_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_GetOccurrenceNote_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": "containeranalysis_v1_generated_grafeas_get_occurrence_note_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.get_occurrence", - "method": { - "fullName": "grafeas.v1.Grafeas.GetOccurrence", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "GetOccurrence" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.GetOccurrenceRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.Occurrence", - "shortName": "get_occurrence" - }, - "description": "Sample for GetOccurrence", - "file": "containeranalysis_v1_generated_grafeas_get_occurrence_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_GetOccurrence_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": "containeranalysis_v1_generated_grafeas_get_occurrence_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.get_occurrence", - "method": { - "fullName": "grafeas.v1.Grafeas.GetOccurrence", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "GetOccurrence" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.GetOccurrenceRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.types.Occurrence", - "shortName": "get_occurrence" - }, - "description": "Sample for GetOccurrence", - "file": "containeranalysis_v1_generated_grafeas_get_occurrence_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_GetOccurrence_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": "containeranalysis_v1_generated_grafeas_get_occurrence_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.list_note_occurrences", - "method": { - "fullName": "grafeas.v1.Grafeas.ListNoteOccurrences", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "ListNoteOccurrences" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.ListNoteOccurrencesRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "filter", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesAsyncPager", - "shortName": "list_note_occurrences" - }, - "description": "Sample for ListNoteOccurrences", - "file": "containeranalysis_v1_generated_grafeas_list_note_occurrences_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_ListNoteOccurrences_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": "containeranalysis_v1_generated_grafeas_list_note_occurrences_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.list_note_occurrences", - "method": { - "fullName": "grafeas.v1.Grafeas.ListNoteOccurrences", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "ListNoteOccurrences" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.ListNoteOccurrencesRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "filter", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesPager", - "shortName": "list_note_occurrences" - }, - "description": "Sample for ListNoteOccurrences", - "file": "containeranalysis_v1_generated_grafeas_list_note_occurrences_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_ListNoteOccurrences_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": "containeranalysis_v1_generated_grafeas_list_note_occurrences_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.list_notes", - "method": { - "fullName": "grafeas.v1.Grafeas.ListNotes", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "ListNotes" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.ListNotesRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "filter", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListNotesAsyncPager", - "shortName": "list_notes" - }, - "description": "Sample for ListNotes", - "file": "containeranalysis_v1_generated_grafeas_list_notes_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_ListNotes_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": "containeranalysis_v1_generated_grafeas_list_notes_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.list_notes", - "method": { - "fullName": "grafeas.v1.Grafeas.ListNotes", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "ListNotes" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.ListNotesRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "filter", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListNotesPager", - "shortName": "list_notes" - }, - "description": "Sample for ListNotes", - "file": "containeranalysis_v1_generated_grafeas_list_notes_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_ListNotes_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": "containeranalysis_v1_generated_grafeas_list_notes_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.list_occurrences", - "method": { - "fullName": "grafeas.v1.Grafeas.ListOccurrences", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "ListOccurrences" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.ListOccurrencesRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "filter", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesAsyncPager", - "shortName": "list_occurrences" - }, - "description": "Sample for ListOccurrences", - "file": "containeranalysis_v1_generated_grafeas_list_occurrences_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_ListOccurrences_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": "containeranalysis_v1_generated_grafeas_list_occurrences_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.list_occurrences", - "method": { - "fullName": "grafeas.v1.Grafeas.ListOccurrences", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "ListOccurrences" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.ListOccurrencesRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "filter", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesPager", - "shortName": "list_occurrences" - }, - "description": "Sample for ListOccurrences", - "file": "containeranalysis_v1_generated_grafeas_list_occurrences_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_ListOccurrences_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": "containeranalysis_v1_generated_grafeas_list_occurrences_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.update_note", - "method": { - "fullName": "grafeas.v1.Grafeas.UpdateNote", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "UpdateNote" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.UpdateNoteRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "note", - "type": "grafeas.grafeas_v1.types.Note" - }, - { - "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": "grafeas.grafeas_v1.types.Note", - "shortName": "update_note" - }, - "description": "Sample for UpdateNote", - "file": "containeranalysis_v1_generated_grafeas_update_note_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_UpdateNote_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": "containeranalysis_v1_generated_grafeas_update_note_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.update_note", - "method": { - "fullName": "grafeas.v1.Grafeas.UpdateNote", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "UpdateNote" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.UpdateNoteRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "note", - "type": "grafeas.grafeas_v1.types.Note" - }, - { - "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": "grafeas.grafeas_v1.types.Note", - "shortName": "update_note" - }, - "description": "Sample for UpdateNote", - "file": "containeranalysis_v1_generated_grafeas_update_note_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_UpdateNote_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": "containeranalysis_v1_generated_grafeas_update_note_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient", - "shortName": "GrafeasAsyncClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasAsyncClient.update_occurrence", - "method": { - "fullName": "grafeas.v1.Grafeas.UpdateOccurrence", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "UpdateOccurrence" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.UpdateOccurrenceRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "occurrence", - "type": "grafeas.grafeas_v1.types.Occurrence" - }, - { - "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": "grafeas.grafeas_v1.types.Occurrence", - "shortName": "update_occurrence" - }, - "description": "Sample for UpdateOccurrence", - "file": "containeranalysis_v1_generated_grafeas_update_occurrence_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_UpdateOccurrence_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": "containeranalysis_v1_generated_grafeas_update_occurrence_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "grafeas.grafeas_v1.GrafeasClient", - "shortName": "GrafeasClient" - }, - "fullName": "grafeas.grafeas_v1.GrafeasClient.update_occurrence", - "method": { - "fullName": "grafeas.v1.Grafeas.UpdateOccurrence", - "service": { - "fullName": "grafeas.v1.Grafeas", - "shortName": "Grafeas" - }, - "shortName": "UpdateOccurrence" - }, - "parameters": [ - { - "name": "request", - "type": "grafeas.grafeas_v1.types.UpdateOccurrenceRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "occurrence", - "type": "grafeas.grafeas_v1.types.Occurrence" - }, - { - "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": "grafeas.grafeas_v1.types.Occurrence", - "shortName": "update_occurrence" - }, - "description": "Sample for UpdateOccurrence", - "file": "containeranalysis_v1_generated_grafeas_update_occurrence_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "containeranalysis_v1_generated_Grafeas_UpdateOccurrence_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": "containeranalysis_v1_generated_grafeas_update_occurrence_sync.py" - } - ] -} diff --git a/owl-bot-staging/grafeas/v1/scripts/fixup_grafeas_v1_keywords.py b/owl-bot-staging/grafeas/v1/scripts/fixup_grafeas_v1_keywords.py deleted file mode 100644 index 78bae6683cc8..000000000000 --- a/owl-bot-staging/grafeas/v1/scripts/fixup_grafeas_v1_keywords.py +++ /dev/null @@ -1,189 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 grafeasCallTransformer(cst.CSTTransformer): - CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') - METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { - 'batch_create_notes': ('parent', 'notes', ), - 'batch_create_occurrences': ('parent', 'occurrences', ), - 'create_note': ('parent', 'note_id', 'note', ), - 'create_occurrence': ('parent', 'occurrence', ), - 'delete_note': ('name', ), - 'delete_occurrence': ('name', ), - 'get_note': ('name', ), - 'get_occurrence': ('name', ), - 'get_occurrence_note': ('name', ), - 'list_note_occurrences': ('name', 'filter', 'page_size', 'page_token', ), - 'list_notes': ('parent', 'filter', 'page_size', 'page_token', ), - 'list_occurrences': ('parent', 'filter', 'page_size', 'page_token', ), - 'update_note': ('name', 'note', 'update_mask', ), - 'update_occurrence': ('name', 'occurrence', 'update_mask', ), - } - - def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: - try: - key = original.func.attr.value - kword_params = self.METHOD_TO_PARAMS[key] - except (AttributeError, KeyError): - # Either not a method from the API or too convoluted to be sure. - return updated - - # If the existing code is valid, keyword args come after positional args. - # Therefore, all positional args must map to the first parameters. - args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) - if any(k.keyword.value == "request" for k in kwargs): - # We've already fixed this file, don't fix it again. - return updated - - kwargs, ctrl_kwargs = partition( - lambda a: a.keyword.value not in self.CTRL_PARAMS, - kwargs - ) - - args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] - ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) - for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) - - request_arg = cst.Arg( - value=cst.Dict([ - cst.DictElement( - cst.SimpleString("'{}'".format(name)), -cst.Element(value=arg.value) - ) - # Note: the args + kwargs looks silly, but keep in mind that - # the control parameters had to be stripped out, and that - # those could have been passed positionally or by keyword. - for name, arg in zip(kword_params, args + kwargs)]), - keyword=cst.Name("request") - ) - - return updated.with_changes( - args=[request_arg] + ctrl_kwargs - ) - - -def fix_files( - in_dir: pathlib.Path, - out_dir: pathlib.Path, - *, - transformer=grafeasCallTransformer(), -): - """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 grafeas 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/grafeas/v1/setup.py b/owl-bot-staging/grafeas/v1/setup.py deleted file mode 100644 index 42545da2ab4f..000000000000 --- a/owl-bot-staging/grafeas/v1/setup.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 re - -import setuptools # type: ignore - -package_root = os.path.abspath(os.path.dirname(__file__)) - -name = 'grafeas' - - -description = "Grafeas API client library" - -version = None - -with open(os.path.join(package_root, 'grafeas/grafeas/gapic_version.py')) as fp: - version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) - assert (len(version_candidates) == 1) - version = version_candidates[0] - -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.1, <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.*", - # Exclude incompatible versions of `google-auth` - # See https://github.com/googleapis/google-cloud-python/issues/12364 - "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", - "proto-plus >= 1.22.3, <2.0.0dev", - "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", - "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", -] -extras = { -} -url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/grafeas" - -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.find_namespace_packages() - if package.startswith("grafeas") -] - -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", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Operating System :: OS Independent", - "Topic :: Internet", - ], - platforms="Posix; MacOS X; Windows", - packages=packages, - python_requires=">=3.7", - install_requires=dependencies, - extras_require=extras, - include_package_data=True, - zip_safe=False, -) diff --git a/owl-bot-staging/grafeas/v1/testing/constraints-3.10.txt b/owl-bot-staging/grafeas/v1/testing/constraints-3.10.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/grafeas/v1/testing/constraints-3.10.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/grafeas/v1/testing/constraints-3.11.txt b/owl-bot-staging/grafeas/v1/testing/constraints-3.11.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/grafeas/v1/testing/constraints-3.11.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/grafeas/v1/testing/constraints-3.12.txt b/owl-bot-staging/grafeas/v1/testing/constraints-3.12.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/grafeas/v1/testing/constraints-3.12.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/grafeas/v1/testing/constraints-3.7.txt b/owl-bot-staging/grafeas/v1/testing/constraints-3.7.txt deleted file mode 100644 index fc812592b0ee..000000000000 --- a/owl-bot-staging/grafeas/v1/testing/constraints-3.7.txt +++ /dev/null @@ -1,10 +0,0 @@ -# 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.1 -google-auth==2.14.1 -proto-plus==1.22.3 -protobuf==3.20.2 diff --git a/owl-bot-staging/grafeas/v1/testing/constraints-3.8.txt b/owl-bot-staging/grafeas/v1/testing/constraints-3.8.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/grafeas/v1/testing/constraints-3.8.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/grafeas/v1/testing/constraints-3.9.txt b/owl-bot-staging/grafeas/v1/testing/constraints-3.9.txt deleted file mode 100644 index ed7f9aed2559..000000000000 --- a/owl-bot-staging/grafeas/v1/testing/constraints-3.9.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- 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/grafeas/v1/tests/__init__.py b/owl-bot-staging/grafeas/v1/tests/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/grafeas/v1/tests/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/grafeas/v1/tests/unit/__init__.py b/owl-bot-staging/grafeas/v1/tests/unit/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/grafeas/v1/tests/unit/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/grafeas/v1/tests/unit/gapic/__init__.py b/owl-bot-staging/grafeas/v1/tests/unit/gapic/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/grafeas/v1/tests/unit/gapic/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/grafeas/v1/tests/unit/gapic/grafeas_v1/__init__.py b/owl-bot-staging/grafeas/v1/tests/unit/gapic/grafeas_v1/__init__.py deleted file mode 100644 index 7b3de3117f38..000000000000 --- a/owl-bot-staging/grafeas/v1/tests/unit/gapic/grafeas_v1/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ - -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/grafeas/v1/tests/unit/gapic/grafeas_v1/test_grafeas.py b/owl-bot-staging/grafeas/v1/tests/unit/gapic/grafeas_v1/test_grafeas.py deleted file mode 100644 index 9d115bd76b9d..000000000000 --- a/owl-bot-staging/grafeas/v1/tests/unit/gapic/grafeas_v1/test_grafeas.py +++ /dev/null @@ -1,11984 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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, AsyncIterable -from google.protobuf import json_format -import json -import math -import pytest -from google.api_core import api_core_version -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 - -try: - from google.auth.aio import credentials as ga_credentials_async - HAS_GOOGLE_AUTH_AIO = True -except ImportError: # pragma: NO COVER - HAS_GOOGLE_AUTH_AIO = False - -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.api_core import retry as retries -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account -from google.protobuf import any_pb2 # type: ignore -from google.protobuf import field_mask_pb2 # type: ignore -from google.protobuf import struct_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -from google.rpc import status_pb2 # type: ignore -from grafeas.grafeas_v1.services.grafeas import GrafeasAsyncClient -from grafeas.grafeas_v1.services.grafeas import GrafeasClient -from grafeas.grafeas_v1.services.grafeas import pagers -from grafeas.grafeas_v1.services.grafeas import transports -from grafeas.grafeas_v1.types import attestation -from grafeas.grafeas_v1.types import build -from grafeas.grafeas_v1.types import common -from grafeas.grafeas_v1.types import compliance -from grafeas.grafeas_v1.types import cvss -from grafeas.grafeas_v1.types import deployment -from grafeas.grafeas_v1.types import discovery -from grafeas.grafeas_v1.types import dsse_attestation -from grafeas.grafeas_v1.types import grafeas -from grafeas.grafeas_v1.types import image -from grafeas.grafeas_v1.types import intoto_provenance -from grafeas.grafeas_v1.types import intoto_statement -from grafeas.grafeas_v1.types import package -from grafeas.grafeas_v1.types import provenance -from grafeas.grafeas_v1.types import sbom -from grafeas.grafeas_v1.types import severity -from grafeas.grafeas_v1.types import slsa_provenance -from grafeas.grafeas_v1.types import slsa_provenance_zero_two -from grafeas.grafeas_v1.types import upgrade -from grafeas.grafeas_v1.types import vex -from grafeas.grafeas_v1.types import vulnerability -import google.auth - - -async def mock_async_gen(data, chunk_size=1): - for i in range(0, len(data)): # pragma: NO COVER - chunk = data[i : i + chunk_size] - yield chunk.encode("utf-8") - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - -# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. -# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. -def async_anonymous_credentials(): - if HAS_GOOGLE_AUTH_AIO: - return ga_credentials_async.AnonymousCredentials() - return ga_credentials.AnonymousCredentials() - -# 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 - -# If default endpoint template is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint template so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint_template(client): - return "test.{UNIVERSE_DOMAIN}" if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) else client._DEFAULT_ENDPOINT_TEMPLATE - - -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 GrafeasClient._get_default_mtls_endpoint(None) is None - assert GrafeasClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint - assert GrafeasClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint - assert GrafeasClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint - assert GrafeasClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint - assert GrafeasClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - -def test__read_environment_variables(): - assert GrafeasClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert GrafeasClient._read_environment_variables() == (True, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - assert GrafeasClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError) as excinfo: - GrafeasClient._read_environment_variables() - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - assert GrafeasClient._read_environment_variables() == (False, "never", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - assert GrafeasClient._read_environment_variables() == (False, "always", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): - assert GrafeasClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - GrafeasClient._read_environment_variables() - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): - assert GrafeasClient._read_environment_variables() == (False, "auto", "foo.com") - -def test__get_client_cert_source(): - mock_provided_cert_source = mock.Mock() - mock_default_cert_source = mock.Mock() - - assert GrafeasClient._get_client_cert_source(None, False) is None - assert GrafeasClient._get_client_cert_source(mock_provided_cert_source, False) is None - assert GrafeasClient._get_client_cert_source(mock_provided_cert_source, True) == mock_provided_cert_source - - 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_default_cert_source): - assert GrafeasClient._get_client_cert_source(None, True) is mock_default_cert_source - assert GrafeasClient._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source - -@mock.patch.object(GrafeasClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasClient)) -@mock.patch.object(GrafeasAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasAsyncClient)) -def test__get_api_endpoint(): - api_override = "foo.com" - mock_client_cert_source = mock.Mock() - default_universe = GrafeasClient._DEFAULT_UNIVERSE - default_endpoint = GrafeasClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) - mock_universe = "bar.com" - mock_endpoint = GrafeasClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) - - assert GrafeasClient._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override - assert GrafeasClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == GrafeasClient.DEFAULT_MTLS_ENDPOINT - assert GrafeasClient._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint - assert GrafeasClient._get_api_endpoint(None, None, default_universe, "always") == GrafeasClient.DEFAULT_MTLS_ENDPOINT - assert GrafeasClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == GrafeasClient.DEFAULT_MTLS_ENDPOINT - assert GrafeasClient._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint - assert GrafeasClient._get_api_endpoint(None, None, default_universe, "never") == default_endpoint - - with pytest.raises(MutualTLSChannelError) as excinfo: - GrafeasClient._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto") - assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com." - - -def test__get_universe_domain(): - client_universe_domain = "foo.com" - universe_domain_env = "bar.com" - - assert GrafeasClient._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain - assert GrafeasClient._get_universe_domain(None, universe_domain_env) == universe_domain_env - assert GrafeasClient._get_universe_domain(None, None) == GrafeasClient._DEFAULT_UNIVERSE - - with pytest.raises(ValueError) as excinfo: - GrafeasClient._get_universe_domain("", None) - assert str(excinfo.value) == "Universe Domain cannot be an empty string." - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (GrafeasClient, transports.GrafeasGrpcTransport, "grpc"), - (GrafeasClient, transports.GrafeasRestTransport, "rest"), -]) -def test__validate_universe_domain(client_class, transport_class, transport_name): - client = client_class( - transport=transport_class( - credentials=ga_credentials.AnonymousCredentials() - ) - ) - assert client._validate_universe_domain() == True - - # Test the case when universe is already validated. - assert client._validate_universe_domain() == True - - if transport_name == "grpc": - # Test the case where credentials are provided by the - # `local_channel_credentials`. The default universes in both match. - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - client = client_class(transport=transport_class(channel=channel)) - assert client._validate_universe_domain() == True - - # Test the case where credentials do not exist: e.g. a transport is provided - # with no credentials. Validation should still succeed because there is no - # mismatch with non-existent credentials. - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - transport=transport_class(channel=channel) - transport._credentials = None - client = client_class(transport=transport) - assert client._validate_universe_domain() == True - - # TODO: This is needed to cater for older versions of google-auth - # Make this test unconditional once the minimum supported version of - # google-auth becomes 2.23.0 or higher. - google_auth_major, google_auth_minor = [int(part) for part in google.auth.__version__.split(".")[0:2]] - if google_auth_major > 2 or (google_auth_major == 2 and google_auth_minor >= 23): - credentials = ga_credentials.AnonymousCredentials() - credentials._universe_domain = "foo.com" - # Test the case when there is a universe mismatch from the credentials. - client = client_class( - transport=transport_class(credentials=credentials) - ) - with pytest.raises(ValueError) as excinfo: - client._validate_universe_domain() - assert str(excinfo.value) == "The configured universe domain (googleapis.com) does not match the universe domain found in the credentials (foo.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." - - # Test the case when there is a universe mismatch from the client. - # - # TODO: Make this test unconditional once the minimum supported version of - # google-api-core becomes 2.15.0 or higher. - api_core_major, api_core_minor = [int(part) for part in api_core_version.__version__.split(".")[0:2]] - if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 15): - client = client_class(client_options={"universe_domain": "bar.com"}, transport=transport_class(credentials=ga_credentials.AnonymousCredentials(),)) - with pytest.raises(ValueError) as excinfo: - client._validate_universe_domain() - assert str(excinfo.value) == "The configured universe domain (bar.com) does not match the universe domain found in the credentials (googleapis.com). If you haven't configured the universe domain explicitly, `googleapis.com` is the default." - - # Test that ValueError is raised if universe_domain is provided via client options and credentials is None - with pytest.raises(ValueError): - client._compare_universes("foo.bar", None) - - -@pytest.mark.parametrize("client_class,transport_name", [ - (GrafeasClient, "grpc"), - (GrafeasAsyncClient, "grpc_asyncio"), - (GrafeasClient, "rest"), -]) -def test_grafeas_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 == ( - 'containeranalysis.googleapis.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else - 'https://containeranalysis.googleapis.com' - ) - - -@pytest.mark.parametrize("transport_class,transport_name", [ - (transports.GrafeasGrpcTransport, "grpc"), - (transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio"), - (transports.GrafeasRestTransport, "rest"), -]) -def test_grafeas_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", [ - (GrafeasClient, "grpc"), - (GrafeasAsyncClient, "grpc_asyncio"), - (GrafeasClient, "rest"), -]) -def test_grafeas_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 == ( - 'containeranalysis.googleapis.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else - 'https://containeranalysis.googleapis.com' - ) - - -def test_grafeas_client_get_transport_class(): - transport = GrafeasClient.get_transport_class() - available_transports = [ - transports.GrafeasGrpcTransport, - transports.GrafeasRestTransport, - ] - assert transport in available_transports - - transport = GrafeasClient.get_transport_class("grpc") - assert transport == transports.GrafeasGrpcTransport - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (GrafeasClient, transports.GrafeasGrpcTransport, "grpc"), - (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio"), - (GrafeasClient, transports.GrafeasRestTransport, "rest"), -]) -@mock.patch.object(GrafeasClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasClient)) -@mock.patch.object(GrafeasAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasAsyncClient)) -def test_grafeas_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(GrafeasClient, '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(GrafeasClient, '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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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) as excinfo: - client = client_class(transport=transport_name) - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - # 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) as excinfo: - client = client_class(transport=transport_name) - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - - # 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - 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", [ - (GrafeasClient, transports.GrafeasGrpcTransport, "grpc", "true"), - (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio", "true"), - (GrafeasClient, transports.GrafeasGrpcTransport, "grpc", "false"), - (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio", "false"), - (GrafeasClient, transports.GrafeasRestTransport, "rest", "true"), - (GrafeasClient, transports.GrafeasRestTransport, "rest", "false"), -]) -@mock.patch.object(GrafeasClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasClient)) -@mock.patch.object(GrafeasAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasAsyncClient)) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_grafeas_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) - 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) - 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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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", [ - GrafeasClient, GrafeasAsyncClient -]) -@mock.patch.object(GrafeasClient, "DEFAULT_ENDPOINT", modify_default_endpoint(GrafeasClient)) -@mock.patch.object(GrafeasAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(GrafeasAsyncClient)) -def test_grafeas_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 - - # 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) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - # 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) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - -@pytest.mark.parametrize("client_class", [ - GrafeasClient, GrafeasAsyncClient -]) -@mock.patch.object(GrafeasClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasClient)) -@mock.patch.object(GrafeasAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(GrafeasAsyncClient)) -def test_grafeas_client_client_api_endpoint(client_class): - mock_client_cert_source = client_cert_source_callback - api_override = "foo.com" - default_universe = GrafeasClient._DEFAULT_UNIVERSE - default_endpoint = GrafeasClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) - mock_universe = "bar.com" - mock_endpoint = GrafeasClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) - - # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", - # use ClientOptions.api_endpoint as the api endpoint regardless. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel"): - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=api_override) - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == api_override - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", - # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - - # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), - # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, - # and ClientOptions.universe_domain="bar.com", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. - options = client_options.ClientOptions() - universe_exists = hasattr(options, "universe_domain") - if universe_exists: - options = client_options.ClientOptions(universe_domain=mock_universe) - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - else: - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == (mock_endpoint if universe_exists else default_endpoint) - assert client.universe_domain == (mock_universe if universe_exists else default_universe) - - # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - options = client_options.ClientOptions() - if hasattr(options, "universe_domain"): - delattr(options, "universe_domain") - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (GrafeasClient, transports.GrafeasGrpcTransport, "grpc"), - (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio"), - (GrafeasClient, transports.GrafeasRestTransport, "rest"), -]) -def test_grafeas_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - 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", [ - (GrafeasClient, transports.GrafeasGrpcTransport, "grpc", grpc_helpers), - (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), - (GrafeasClient, transports.GrafeasRestTransport, "rest", None), -]) -def test_grafeas_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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_grafeas_client_client_options_from_dict(): - with mock.patch('grafeas.grafeas_v1.services.grafeas.transports.GrafeasGrpcTransport.__init__') as grpc_transport: - grpc_transport.return_value = None - client = GrafeasClient( - 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", [ - (GrafeasClient, transports.GrafeasGrpcTransport, "grpc", grpc_helpers), - (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), -]) -def test_grafeas_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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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( - "containeranalysis.googleapis.com:443", - credentials=file_creds, - credentials_file=None, - quota_project_id=None, - default_scopes=( -), - scopes=None, - default_host="containeranalysis.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("request_type", [ - grafeas.GetOccurrenceRequest, - dict, -]) -def test_get_occurrence(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Occurrence( - name='name_value', - resource_uri='resource_uri_value', - note_name='note_name_value', - kind=common.NoteKind.VULNERABILITY, - remediation='remediation_value', - ) - response = client.get_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.GetOccurrenceRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Occurrence) - assert response.name == 'name_value' - assert response.resource_uri == 'resource_uri_value' - assert response.note_name == 'note_name_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.remediation == 'remediation_value' - - -def test_get_occurrence_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.GetOccurrenceRequest( - name='name_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.get_occurrence(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.GetOccurrenceRequest( - name='name_value', - ) - -def test_get_occurrence_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_occurrence in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.get_occurrence] = mock_rpc - request = {} - client.get_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.get_occurrence(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_get_occurrence_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.get_occurrence in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.get_occurrence] = mock_rpc - - request = {} - await client.get_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.get_occurrence(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_get_occurrence_async(transport: str = 'grpc_asyncio', request_type=grafeas.GetOccurrenceRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence( - name='name_value', - resource_uri='resource_uri_value', - note_name='note_name_value', - kind=common.NoteKind.VULNERABILITY, - remediation='remediation_value', - )) - response = await client.get_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.GetOccurrenceRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Occurrence) - assert response.name == 'name_value' - assert response.resource_uri == 'resource_uri_value' - assert response.note_name == 'note_name_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.remediation == 'remediation_value' - - -@pytest.mark.asyncio -async def test_get_occurrence_async_from_dict(): - await test_get_occurrence_async(request_type=dict) - -def test_get_occurrence_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.GetOccurrenceRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence), - '__call__') as call: - call.return_value = grafeas.Occurrence() - client.get_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_occurrence_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.GetOccurrenceRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence()) - await client.get_occurrence(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_occurrence_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Occurrence() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.get_occurrence( - 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_occurrence_flattened_error(): - client = GrafeasClient( - 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_occurrence( - grafeas.GetOccurrenceRequest(), - name='name_value', - ) - -@pytest.mark.asyncio -async def test_get_occurrence_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Occurrence() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.get_occurrence( - 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_occurrence_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.get_occurrence( - grafeas.GetOccurrenceRequest(), - name='name_value', - ) - - -@pytest.mark.parametrize("request_type", [ - grafeas.ListOccurrencesRequest, - dict, -]) -def test_list_occurrences(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.ListOccurrencesResponse( - next_page_token='next_page_token_value', - ) - response = client.list_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.ListOccurrencesRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListOccurrencesPager) - assert response.next_page_token == 'next_page_token_value' - - -def test_list_occurrences_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.ListOccurrencesRequest( - parent='parent_value', - filter='filter_value', - page_token='page_token_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_occurrences), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.list_occurrences(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.ListOccurrencesRequest( - parent='parent_value', - filter='filter_value', - page_token='page_token_value', - ) - -def test_list_occurrences_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_occurrences in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.list_occurrences] = mock_rpc - request = {} - client.list_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_occurrences(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_occurrences_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.list_occurrences in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.list_occurrences] = mock_rpc - - request = {} - await client.list_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.list_occurrences(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_occurrences_async(transport: str = 'grpc_asyncio', request_type=grafeas.ListOccurrencesRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListOccurrencesResponse( - next_page_token='next_page_token_value', - )) - response = await client.list_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.ListOccurrencesRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListOccurrencesAsyncPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.asyncio -async def test_list_occurrences_async_from_dict(): - await test_list_occurrences_async(request_type=dict) - -def test_list_occurrences_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.ListOccurrencesRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_occurrences), - '__call__') as call: - call.return_value = grafeas.ListOccurrencesResponse() - client.list_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_occurrences_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.ListOccurrencesRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_occurrences), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListOccurrencesResponse()) - await client.list_occurrences(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_occurrences_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.ListOccurrencesResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.list_occurrences( - parent='parent_value', - filter='filter_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].filter - mock_val = 'filter_value' - assert arg == mock_val - - -def test_list_occurrences_flattened_error(): - client = GrafeasClient( - 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_occurrences( - grafeas.ListOccurrencesRequest(), - parent='parent_value', - filter='filter_value', - ) - -@pytest.mark.asyncio -async def test_list_occurrences_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.ListOccurrencesResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListOccurrencesResponse()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.list_occurrences( - parent='parent_value', - filter='filter_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].filter - mock_val = 'filter_value' - assert arg == mock_val - -@pytest.mark.asyncio -async def test_list_occurrences_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.list_occurrences( - grafeas.ListOccurrencesRequest(), - parent='parent_value', - filter='filter_value', - ) - - -def test_list_occurrences_pager(transport_name: str = "grpc"): - client = GrafeasClient( - 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_occurrences), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - next_page_token='abc', - ), - grafeas.ListOccurrencesResponse( - occurrences=[], - next_page_token='def', - ), - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - ], - next_page_token='ghi', - ), - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - ), - RuntimeError, - ) - - expected_metadata = () - retry = retries.Retry() - timeout = 5 - expected_metadata = tuple(expected_metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ('parent', ''), - )), - ) - pager = client.list_occurrences(request={}, retry=retry, timeout=timeout) - - assert pager._metadata == expected_metadata - assert pager._retry == retry - assert pager._timeout == timeout - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, grafeas.Occurrence) - for i in results) -def test_list_occurrences_pages(transport_name: str = "grpc"): - client = GrafeasClient( - 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_occurrences), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - next_page_token='abc', - ), - grafeas.ListOccurrencesResponse( - occurrences=[], - next_page_token='def', - ), - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - ], - next_page_token='ghi', - ), - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - ), - RuntimeError, - ) - pages = list(client.list_occurrences(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_occurrences_async_pager(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_occurrences), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - next_page_token='abc', - ), - grafeas.ListOccurrencesResponse( - occurrences=[], - next_page_token='def', - ), - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - ], - next_page_token='ghi', - ), - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - ), - RuntimeError, - ) - async_pager = await client.list_occurrences(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, grafeas.Occurrence) - for i in responses) - - -@pytest.mark.asyncio -async def test_list_occurrences_async_pages(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_occurrences), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - next_page_token='abc', - ), - grafeas.ListOccurrencesResponse( - occurrences=[], - next_page_token='def', - ), - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - ], - next_page_token='ghi', - ), - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - ), - 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_occurrences(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", [ - grafeas.DeleteOccurrenceRequest, - dict, -]) -def test_delete_occurrence(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = None - response = client.delete_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.DeleteOccurrenceRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert response is None - - -def test_delete_occurrence_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.DeleteOccurrenceRequest( - name='name_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_occurrence), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.delete_occurrence(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.DeleteOccurrenceRequest( - name='name_value', - ) - -def test_delete_occurrence_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.delete_occurrence in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.delete_occurrence] = mock_rpc - request = {} - client.delete_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.delete_occurrence(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_delete_occurrence_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.delete_occurrence in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.delete_occurrence] = mock_rpc - - request = {} - await client.delete_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.delete_occurrence(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_delete_occurrence_async(transport: str = 'grpc_asyncio', request_type=grafeas.DeleteOccurrenceRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.DeleteOccurrenceRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert response is None - - -@pytest.mark.asyncio -async def test_delete_occurrence_async_from_dict(): - await test_delete_occurrence_async(request_type=dict) - -def test_delete_occurrence_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.DeleteOccurrenceRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_occurrence), - '__call__') as call: - call.return_value = None - client.delete_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_occurrence_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.DeleteOccurrenceRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_occurrence), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - await client.delete_occurrence(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_occurrence_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_occurrence), - '__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_occurrence( - 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_occurrence_flattened_error(): - client = GrafeasClient( - 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_occurrence( - grafeas.DeleteOccurrenceRequest(), - name='name_value', - ) - -@pytest.mark.asyncio -async def test_delete_occurrence_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_occurrence), - '__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_occurrence( - 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_occurrence_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.delete_occurrence( - grafeas.DeleteOccurrenceRequest(), - name='name_value', - ) - - -@pytest.mark.parametrize("request_type", [ - grafeas.CreateOccurrenceRequest, - dict, -]) -def test_create_occurrence(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Occurrence( - name='name_value', - resource_uri='resource_uri_value', - note_name='note_name_value', - kind=common.NoteKind.VULNERABILITY, - remediation='remediation_value', - ) - response = client.create_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.CreateOccurrenceRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Occurrence) - assert response.name == 'name_value' - assert response.resource_uri == 'resource_uri_value' - assert response.note_name == 'note_name_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.remediation == 'remediation_value' - - -def test_create_occurrence_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.CreateOccurrenceRequest( - parent='parent_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_occurrence), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.create_occurrence(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.CreateOccurrenceRequest( - parent='parent_value', - ) - -def test_create_occurrence_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.create_occurrence in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.create_occurrence] = mock_rpc - request = {} - client.create_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.create_occurrence(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_create_occurrence_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.create_occurrence in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.create_occurrence] = mock_rpc - - request = {} - await client.create_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.create_occurrence(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_create_occurrence_async(transport: str = 'grpc_asyncio', request_type=grafeas.CreateOccurrenceRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence( - name='name_value', - resource_uri='resource_uri_value', - note_name='note_name_value', - kind=common.NoteKind.VULNERABILITY, - remediation='remediation_value', - )) - response = await client.create_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.CreateOccurrenceRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Occurrence) - assert response.name == 'name_value' - assert response.resource_uri == 'resource_uri_value' - assert response.note_name == 'note_name_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.remediation == 'remediation_value' - - -@pytest.mark.asyncio -async def test_create_occurrence_async_from_dict(): - await test_create_occurrence_async(request_type=dict) - -def test_create_occurrence_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.CreateOccurrenceRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_occurrence), - '__call__') as call: - call.return_value = grafeas.Occurrence() - client.create_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_occurrence_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.CreateOccurrenceRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_occurrence), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence()) - await client.create_occurrence(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_occurrence_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Occurrence() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.create_occurrence( - parent='parent_value', - occurrence=grafeas.Occurrence(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].occurrence - mock_val = grafeas.Occurrence(name='name_value') - assert arg == mock_val - - -def test_create_occurrence_flattened_error(): - client = GrafeasClient( - 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_occurrence( - grafeas.CreateOccurrenceRequest(), - parent='parent_value', - occurrence=grafeas.Occurrence(name='name_value'), - ) - -@pytest.mark.asyncio -async def test_create_occurrence_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Occurrence() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.create_occurrence( - parent='parent_value', - occurrence=grafeas.Occurrence(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].occurrence - mock_val = grafeas.Occurrence(name='name_value') - assert arg == mock_val - -@pytest.mark.asyncio -async def test_create_occurrence_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.create_occurrence( - grafeas.CreateOccurrenceRequest(), - parent='parent_value', - occurrence=grafeas.Occurrence(name='name_value'), - ) - - -@pytest.mark.parametrize("request_type", [ - grafeas.BatchCreateOccurrencesRequest, - dict, -]) -def test_batch_create_occurrences(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_create_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.BatchCreateOccurrencesResponse( - ) - response = client.batch_create_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.BatchCreateOccurrencesRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.BatchCreateOccurrencesResponse) - - -def test_batch_create_occurrences_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.BatchCreateOccurrencesRequest( - parent='parent_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_occurrences), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.batch_create_occurrences(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.BatchCreateOccurrencesRequest( - parent='parent_value', - ) - -def test_batch_create_occurrences_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.batch_create_occurrences in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.batch_create_occurrences] = mock_rpc - request = {} - client.batch_create_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.batch_create_occurrences(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_batch_create_occurrences_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.batch_create_occurrences in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.batch_create_occurrences] = mock_rpc - - request = {} - await client.batch_create_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.batch_create_occurrences(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_batch_create_occurrences_async(transport: str = 'grpc_asyncio', request_type=grafeas.BatchCreateOccurrencesRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_create_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateOccurrencesResponse( - )) - response = await client.batch_create_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.BatchCreateOccurrencesRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.BatchCreateOccurrencesResponse) - - -@pytest.mark.asyncio -async def test_batch_create_occurrences_async_from_dict(): - await test_batch_create_occurrences_async(request_type=dict) - -def test_batch_create_occurrences_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.BatchCreateOccurrencesRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_occurrences), - '__call__') as call: - call.return_value = grafeas.BatchCreateOccurrencesResponse() - client.batch_create_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_batch_create_occurrences_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.BatchCreateOccurrencesRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_occurrences), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateOccurrencesResponse()) - await client.batch_create_occurrences(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_batch_create_occurrences_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.BatchCreateOccurrencesResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.batch_create_occurrences( - parent='parent_value', - occurrences=[grafeas.Occurrence(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].occurrences - mock_val = [grafeas.Occurrence(name='name_value')] - assert arg == mock_val - - -def test_batch_create_occurrences_flattened_error(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.batch_create_occurrences( - grafeas.BatchCreateOccurrencesRequest(), - parent='parent_value', - occurrences=[grafeas.Occurrence(name='name_value')], - ) - -@pytest.mark.asyncio -async def test_batch_create_occurrences_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.BatchCreateOccurrencesResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateOccurrencesResponse()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.batch_create_occurrences( - parent='parent_value', - occurrences=[grafeas.Occurrence(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].occurrences - mock_val = [grafeas.Occurrence(name='name_value')] - assert arg == mock_val - -@pytest.mark.asyncio -async def test_batch_create_occurrences_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.batch_create_occurrences( - grafeas.BatchCreateOccurrencesRequest(), - parent='parent_value', - occurrences=[grafeas.Occurrence(name='name_value')], - ) - - -@pytest.mark.parametrize("request_type", [ - grafeas.UpdateOccurrenceRequest, - dict, -]) -def test_update_occurrence(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Occurrence( - name='name_value', - resource_uri='resource_uri_value', - note_name='note_name_value', - kind=common.NoteKind.VULNERABILITY, - remediation='remediation_value', - ) - response = client.update_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.UpdateOccurrenceRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Occurrence) - assert response.name == 'name_value' - assert response.resource_uri == 'resource_uri_value' - assert response.note_name == 'note_name_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.remediation == 'remediation_value' - - -def test_update_occurrence_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.UpdateOccurrenceRequest( - name='name_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_occurrence), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.update_occurrence(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.UpdateOccurrenceRequest( - name='name_value', - ) - -def test_update_occurrence_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.update_occurrence in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.update_occurrence] = mock_rpc - request = {} - client.update_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.update_occurrence(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_update_occurrence_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.update_occurrence in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.update_occurrence] = mock_rpc - - request = {} - await client.update_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.update_occurrence(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_update_occurrence_async(transport: str = 'grpc_asyncio', request_type=grafeas.UpdateOccurrenceRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence( - name='name_value', - resource_uri='resource_uri_value', - note_name='note_name_value', - kind=common.NoteKind.VULNERABILITY, - remediation='remediation_value', - )) - response = await client.update_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.UpdateOccurrenceRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Occurrence) - assert response.name == 'name_value' - assert response.resource_uri == 'resource_uri_value' - assert response.note_name == 'note_name_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.remediation == 'remediation_value' - - -@pytest.mark.asyncio -async def test_update_occurrence_async_from_dict(): - await test_update_occurrence_async(request_type=dict) - -def test_update_occurrence_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.UpdateOccurrenceRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_occurrence), - '__call__') as call: - call.return_value = grafeas.Occurrence() - client.update_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_update_occurrence_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.UpdateOccurrenceRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_occurrence), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence()) - await client.update_occurrence(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_update_occurrence_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Occurrence() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.update_occurrence( - name='name_value', - occurrence=grafeas.Occurrence(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].name - mock_val = 'name_value' - assert arg == mock_val - arg = args[0].occurrence - mock_val = grafeas.Occurrence(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_occurrence_flattened_error(): - client = GrafeasClient( - 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_occurrence( - grafeas.UpdateOccurrenceRequest(), - name='name_value', - occurrence=grafeas.Occurrence(name='name_value'), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - -@pytest.mark.asyncio -async def test_update_occurrence_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Occurrence() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.update_occurrence( - name='name_value', - occurrence=grafeas.Occurrence(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].name - mock_val = 'name_value' - assert arg == mock_val - arg = args[0].occurrence - mock_val = grafeas.Occurrence(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_occurrence_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.update_occurrence( - grafeas.UpdateOccurrenceRequest(), - name='name_value', - occurrence=grafeas.Occurrence(name='name_value'), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - -@pytest.mark.parametrize("request_type", [ - grafeas.GetOccurrenceNoteRequest, - dict, -]) -def test_get_occurrence_note(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_occurrence_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - ) - response = client.get_occurrence_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.GetOccurrenceNoteRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == 'name_value' - assert response.short_description == 'short_description_value' - assert response.long_description == 'long_description_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ['related_note_names_value'] - - -def test_get_occurrence_note_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.GetOccurrenceNoteRequest( - name='name_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence_note), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.get_occurrence_note(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.GetOccurrenceNoteRequest( - name='name_value', - ) - -def test_get_occurrence_note_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_occurrence_note in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.get_occurrence_note] = mock_rpc - request = {} - client.get_occurrence_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.get_occurrence_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_get_occurrence_note_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.get_occurrence_note in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.get_occurrence_note] = mock_rpc - - request = {} - await client.get_occurrence_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.get_occurrence_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_get_occurrence_note_async(transport: str = 'grpc_asyncio', request_type=grafeas.GetOccurrenceNoteRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_occurrence_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - )) - response = await client.get_occurrence_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.GetOccurrenceNoteRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == 'name_value' - assert response.short_description == 'short_description_value' - assert response.long_description == 'long_description_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ['related_note_names_value'] - - -@pytest.mark.asyncio -async def test_get_occurrence_note_async_from_dict(): - await test_get_occurrence_note_async(request_type=dict) - -def test_get_occurrence_note_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.GetOccurrenceNoteRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence_note), - '__call__') as call: - call.return_value = grafeas.Note() - client.get_occurrence_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_occurrence_note_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.GetOccurrenceNoteRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence_note), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) - await client.get_occurrence_note(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_occurrence_note_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Note() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.get_occurrence_note( - 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_occurrence_note_flattened_error(): - client = GrafeasClient( - 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_occurrence_note( - grafeas.GetOccurrenceNoteRequest(), - name='name_value', - ) - -@pytest.mark.asyncio -async def test_get_occurrence_note_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Note() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.get_occurrence_note( - 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_occurrence_note_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.get_occurrence_note( - grafeas.GetOccurrenceNoteRequest(), - name='name_value', - ) - - -@pytest.mark.parametrize("request_type", [ - grafeas.GetNoteRequest, - dict, -]) -def test_get_note(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - ) - response = client.get_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.GetNoteRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == 'name_value' - assert response.short_description == 'short_description_value' - assert response.long_description == 'long_description_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ['related_note_names_value'] - - -def test_get_note_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.GetNoteRequest( - name='name_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_note), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.get_note(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.GetNoteRequest( - name='name_value', - ) - -def test_get_note_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_note in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.get_note] = mock_rpc - request = {} - client.get_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.get_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_get_note_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.get_note in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.get_note] = mock_rpc - - request = {} - await client.get_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.get_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_get_note_async(transport: str = 'grpc_asyncio', request_type=grafeas.GetNoteRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - )) - response = await client.get_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.GetNoteRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == 'name_value' - assert response.short_description == 'short_description_value' - assert response.long_description == 'long_description_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ['related_note_names_value'] - - -@pytest.mark.asyncio -async def test_get_note_async_from_dict(): - await test_get_note_async(request_type=dict) - -def test_get_note_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.GetNoteRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_note), - '__call__') as call: - call.return_value = grafeas.Note() - client.get_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_note_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.GetNoteRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_note), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) - await client.get_note(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_note_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Note() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.get_note( - 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_note_flattened_error(): - client = GrafeasClient( - 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_note( - grafeas.GetNoteRequest(), - name='name_value', - ) - -@pytest.mark.asyncio -async def test_get_note_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.get_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Note() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.get_note( - 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_note_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.get_note( - grafeas.GetNoteRequest(), - name='name_value', - ) - - -@pytest.mark.parametrize("request_type", [ - grafeas.ListNotesRequest, - dict, -]) -def test_list_notes(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_notes), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.ListNotesResponse( - next_page_token='next_page_token_value', - ) - response = client.list_notes(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.ListNotesRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListNotesPager) - assert response.next_page_token == 'next_page_token_value' - - -def test_list_notes_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.ListNotesRequest( - parent='parent_value', - filter='filter_value', - page_token='page_token_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_notes), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.list_notes(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.ListNotesRequest( - parent='parent_value', - filter='filter_value', - page_token='page_token_value', - ) - -def test_list_notes_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_notes in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.list_notes] = mock_rpc - request = {} - client.list_notes(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_notes(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_notes_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.list_notes in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.list_notes] = mock_rpc - - request = {} - await client.list_notes(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.list_notes(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_notes_async(transport: str = 'grpc_asyncio', request_type=grafeas.ListNotesRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_notes), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNotesResponse( - next_page_token='next_page_token_value', - )) - response = await client.list_notes(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.ListNotesRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListNotesAsyncPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.asyncio -async def test_list_notes_async_from_dict(): - await test_list_notes_async(request_type=dict) - -def test_list_notes_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.ListNotesRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_notes), - '__call__') as call: - call.return_value = grafeas.ListNotesResponse() - client.list_notes(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_notes_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.ListNotesRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_notes), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNotesResponse()) - await client.list_notes(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_notes_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_notes), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.ListNotesResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.list_notes( - parent='parent_value', - filter='filter_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].filter - mock_val = 'filter_value' - assert arg == mock_val - - -def test_list_notes_flattened_error(): - client = GrafeasClient( - 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_notes( - grafeas.ListNotesRequest(), - parent='parent_value', - filter='filter_value', - ) - -@pytest.mark.asyncio -async def test_list_notes_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_notes), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.ListNotesResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNotesResponse()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.list_notes( - parent='parent_value', - filter='filter_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].filter - mock_val = 'filter_value' - assert arg == mock_val - -@pytest.mark.asyncio -async def test_list_notes_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.list_notes( - grafeas.ListNotesRequest(), - parent='parent_value', - filter='filter_value', - ) - - -def test_list_notes_pager(transport_name: str = "grpc"): - client = GrafeasClient( - 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_notes), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - grafeas.Note(), - grafeas.Note(), - ], - next_page_token='abc', - ), - grafeas.ListNotesResponse( - notes=[], - next_page_token='def', - ), - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - ], - next_page_token='ghi', - ), - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - grafeas.Note(), - ], - ), - RuntimeError, - ) - - expected_metadata = () - retry = retries.Retry() - timeout = 5 - expected_metadata = tuple(expected_metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ('parent', ''), - )), - ) - pager = client.list_notes(request={}, retry=retry, timeout=timeout) - - assert pager._metadata == expected_metadata - assert pager._retry == retry - assert pager._timeout == timeout - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, grafeas.Note) - for i in results) -def test_list_notes_pages(transport_name: str = "grpc"): - client = GrafeasClient( - 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_notes), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - grafeas.Note(), - grafeas.Note(), - ], - next_page_token='abc', - ), - grafeas.ListNotesResponse( - notes=[], - next_page_token='def', - ), - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - ], - next_page_token='ghi', - ), - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - grafeas.Note(), - ], - ), - RuntimeError, - ) - pages = list(client.list_notes(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_notes_async_pager(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_notes), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - grafeas.Note(), - grafeas.Note(), - ], - next_page_token='abc', - ), - grafeas.ListNotesResponse( - notes=[], - next_page_token='def', - ), - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - ], - next_page_token='ghi', - ), - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - grafeas.Note(), - ], - ), - RuntimeError, - ) - async_pager = await client.list_notes(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, grafeas.Note) - for i in responses) - - -@pytest.mark.asyncio -async def test_list_notes_async_pages(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_notes), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - grafeas.Note(), - grafeas.Note(), - ], - next_page_token='abc', - ), - grafeas.ListNotesResponse( - notes=[], - next_page_token='def', - ), - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - ], - next_page_token='ghi', - ), - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - grafeas.Note(), - ], - ), - 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_notes(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", [ - grafeas.DeleteNoteRequest, - dict, -]) -def test_delete_note(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = None - response = client.delete_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.DeleteNoteRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert response is None - - -def test_delete_note_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.DeleteNoteRequest( - name='name_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_note), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.delete_note(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.DeleteNoteRequest( - name='name_value', - ) - -def test_delete_note_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.delete_note in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.delete_note] = mock_rpc - request = {} - client.delete_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.delete_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_delete_note_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.delete_note in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.delete_note] = mock_rpc - - request = {} - await client.delete_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.delete_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_delete_note_async(transport: str = 'grpc_asyncio', request_type=grafeas.DeleteNoteRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - response = await client.delete_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.DeleteNoteRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert response is None - - -@pytest.mark.asyncio -async def test_delete_note_async_from_dict(): - await test_delete_note_async(request_type=dict) - -def test_delete_note_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.DeleteNoteRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_note), - '__call__') as call: - call.return_value = None - client.delete_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_note_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.DeleteNoteRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_note), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - await client.delete_note(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_note_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_note), - '__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_note( - 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_note_flattened_error(): - client = GrafeasClient( - 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_note( - grafeas.DeleteNoteRequest(), - name='name_value', - ) - -@pytest.mark.asyncio -async def test_delete_note_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.delete_note), - '__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_note( - 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_note_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.delete_note( - grafeas.DeleteNoteRequest(), - name='name_value', - ) - - -@pytest.mark.parametrize("request_type", [ - grafeas.CreateNoteRequest, - dict, -]) -def test_create_note(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - ) - response = client.create_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.CreateNoteRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == 'name_value' - assert response.short_description == 'short_description_value' - assert response.long_description == 'long_description_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ['related_note_names_value'] - - -def test_create_note_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.CreateNoteRequest( - parent='parent_value', - note_id='note_id_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_note), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.create_note(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.CreateNoteRequest( - parent='parent_value', - note_id='note_id_value', - ) - -def test_create_note_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.create_note in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.create_note] = mock_rpc - request = {} - client.create_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.create_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_create_note_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.create_note in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.create_note] = mock_rpc - - request = {} - await client.create_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.create_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_create_note_async(transport: str = 'grpc_asyncio', request_type=grafeas.CreateNoteRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - )) - response = await client.create_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.CreateNoteRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == 'name_value' - assert response.short_description == 'short_description_value' - assert response.long_description == 'long_description_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ['related_note_names_value'] - - -@pytest.mark.asyncio -async def test_create_note_async_from_dict(): - await test_create_note_async(request_type=dict) - -def test_create_note_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.CreateNoteRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_note), - '__call__') as call: - call.return_value = grafeas.Note() - client.create_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_note_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.CreateNoteRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_note), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) - await client.create_note(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_note_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Note() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.create_note( - parent='parent_value', - note_id='note_id_value', - note=grafeas.Note(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].note_id - mock_val = 'note_id_value' - assert arg == mock_val - arg = args[0].note - mock_val = grafeas.Note(name='name_value') - assert arg == mock_val - - -def test_create_note_flattened_error(): - client = GrafeasClient( - 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_note( - grafeas.CreateNoteRequest(), - parent='parent_value', - note_id='note_id_value', - note=grafeas.Note(name='name_value'), - ) - -@pytest.mark.asyncio -async def test_create_note_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.create_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Note() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.create_note( - parent='parent_value', - note_id='note_id_value', - note=grafeas.Note(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].note_id - mock_val = 'note_id_value' - assert arg == mock_val - arg = args[0].note - mock_val = grafeas.Note(name='name_value') - assert arg == mock_val - -@pytest.mark.asyncio -async def test_create_note_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.create_note( - grafeas.CreateNoteRequest(), - parent='parent_value', - note_id='note_id_value', - note=grafeas.Note(name='name_value'), - ) - - -@pytest.mark.parametrize("request_type", [ - grafeas.BatchCreateNotesRequest, - dict, -]) -def test_batch_create_notes(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_create_notes), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.BatchCreateNotesResponse( - ) - response = client.batch_create_notes(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.BatchCreateNotesRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.BatchCreateNotesResponse) - - -def test_batch_create_notes_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.BatchCreateNotesRequest( - parent='parent_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_notes), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.batch_create_notes(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.BatchCreateNotesRequest( - parent='parent_value', - ) - -def test_batch_create_notes_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.batch_create_notes in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.batch_create_notes] = mock_rpc - request = {} - client.batch_create_notes(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.batch_create_notes(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_batch_create_notes_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.batch_create_notes in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.batch_create_notes] = mock_rpc - - request = {} - await client.batch_create_notes(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.batch_create_notes(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_batch_create_notes_async(transport: str = 'grpc_asyncio', request_type=grafeas.BatchCreateNotesRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_create_notes), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateNotesResponse( - )) - response = await client.batch_create_notes(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.BatchCreateNotesRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.BatchCreateNotesResponse) - - -@pytest.mark.asyncio -async def test_batch_create_notes_async_from_dict(): - await test_batch_create_notes_async(request_type=dict) - -def test_batch_create_notes_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.BatchCreateNotesRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_notes), - '__call__') as call: - call.return_value = grafeas.BatchCreateNotesResponse() - client.batch_create_notes(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_batch_create_notes_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.BatchCreateNotesRequest() - - request.parent = 'parent_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_notes), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateNotesResponse()) - await client.batch_create_notes(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_batch_create_notes_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_notes), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.BatchCreateNotesResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.batch_create_notes( - parent='parent_value', - notes={'key_value': grafeas.Note(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].notes - mock_val = {'key_value': grafeas.Note(name='name_value')} - assert arg == mock_val - - -def test_batch_create_notes_flattened_error(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.batch_create_notes( - grafeas.BatchCreateNotesRequest(), - parent='parent_value', - notes={'key_value': grafeas.Note(name='name_value')}, - ) - -@pytest.mark.asyncio -async def test_batch_create_notes_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_notes), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.BatchCreateNotesResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateNotesResponse()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.batch_create_notes( - parent='parent_value', - notes={'key_value': grafeas.Note(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].notes - mock_val = {'key_value': grafeas.Note(name='name_value')} - assert arg == mock_val - -@pytest.mark.asyncio -async def test_batch_create_notes_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.batch_create_notes( - grafeas.BatchCreateNotesRequest(), - parent='parent_value', - notes={'key_value': grafeas.Note(name='name_value')}, - ) - - -@pytest.mark.parametrize("request_type", [ - grafeas.UpdateNoteRequest, - dict, -]) -def test_update_note(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - ) - response = client.update_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.UpdateNoteRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == 'name_value' - assert response.short_description == 'short_description_value' - assert response.long_description == 'long_description_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ['related_note_names_value'] - - -def test_update_note_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.UpdateNoteRequest( - name='name_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_note), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.update_note(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.UpdateNoteRequest( - name='name_value', - ) - -def test_update_note_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.update_note in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.update_note] = mock_rpc - request = {} - client.update_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.update_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_update_note_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.update_note in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.update_note] = mock_rpc - - request = {} - await client.update_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.update_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_update_note_async(transport: str = 'grpc_asyncio', request_type=grafeas.UpdateNoteRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - )) - response = await client.update_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.UpdateNoteRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == 'name_value' - assert response.short_description == 'short_description_value' - assert response.long_description == 'long_description_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ['related_note_names_value'] - - -@pytest.mark.asyncio -async def test_update_note_async_from_dict(): - await test_update_note_async(request_type=dict) - -def test_update_note_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.UpdateNoteRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_note), - '__call__') as call: - call.return_value = grafeas.Note() - client.update_note(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.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_update_note_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.UpdateNoteRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_note), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) - await client.update_note(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_update_note_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Note() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.update_note( - name='name_value', - note=grafeas.Note(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].name - mock_val = 'name_value' - assert arg == mock_val - arg = args[0].note - mock_val = grafeas.Note(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_note_flattened_error(): - client = GrafeasClient( - 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_note( - grafeas.UpdateNoteRequest(), - name='name_value', - note=grafeas.Note(name='name_value'), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - -@pytest.mark.asyncio -async def test_update_note_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.update_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.Note() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.update_note( - name='name_value', - note=grafeas.Note(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].name - mock_val = 'name_value' - assert arg == mock_val - arg = args[0].note - mock_val = grafeas.Note(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_note_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.update_note( - grafeas.UpdateNoteRequest(), - name='name_value', - note=grafeas.Note(name='name_value'), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - -@pytest.mark.parametrize("request_type", [ - grafeas.ListNoteOccurrencesRequest, - dict, -]) -def test_list_note_occurrences(request_type, transport: str = 'grpc'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_note_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.ListNoteOccurrencesResponse( - next_page_token='next_page_token_value', - ) - response = client.list_note_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = grafeas.ListNoteOccurrencesRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListNoteOccurrencesPager) - assert response.next_page_token == 'next_page_token_value' - - -def test_list_note_occurrences_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = grafeas.ListNoteOccurrencesRequest( - name='name_value', - filter='filter_value', - page_token='page_token_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_note_occurrences), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.list_note_occurrences(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == grafeas.ListNoteOccurrencesRequest( - name='name_value', - filter='filter_value', - page_token='page_token_value', - ) - -def test_list_note_occurrences_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_note_occurrences in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.list_note_occurrences] = mock_rpc - request = {} - client.list_note_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_note_occurrences(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_note_occurrences_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.list_note_occurrences in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.list_note_occurrences] = mock_rpc - - request = {} - await client.list_note_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.list_note_occurrences(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_note_occurrences_async(transport: str = 'grpc_asyncio', request_type=grafeas.ListNoteOccurrencesRequest): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an 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_note_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNoteOccurrencesResponse( - next_page_token='next_page_token_value', - )) - response = await client.list_note_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = grafeas.ListNoteOccurrencesRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListNoteOccurrencesAsyncPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.asyncio -async def test_list_note_occurrences_async_from_dict(): - await test_list_note_occurrences_async(request_type=dict) - -def test_list_note_occurrences_field_headers(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.ListNoteOccurrencesRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_note_occurrences), - '__call__') as call: - call.return_value = grafeas.ListNoteOccurrencesResponse() - client.list_note_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'name=name_value', - ) in kw['metadata'] - - -@pytest.mark.asyncio -async def test_list_note_occurrences_field_headers_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = grafeas.ListNoteOccurrencesRequest() - - request.name = 'name_value' - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_note_occurrences), - '__call__') as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNoteOccurrencesResponse()) - await client.list_note_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - 'x-goog-request-params', - 'name=name_value', - ) in kw['metadata'] - - -def test_list_note_occurrences_flattened(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_note_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.ListNoteOccurrencesResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.list_note_occurrences( - name='name_value', - filter='filter_value', - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].name - mock_val = 'name_value' - assert arg == mock_val - arg = args[0].filter - mock_val = 'filter_value' - assert arg == mock_val - - -def test_list_note_occurrences_flattened_error(): - client = GrafeasClient( - 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_note_occurrences( - grafeas.ListNoteOccurrencesRequest(), - name='name_value', - filter='filter_value', - ) - -@pytest.mark.asyncio -async def test_list_note_occurrences_flattened_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_note_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grafeas.ListNoteOccurrencesResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNoteOccurrencesResponse()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.list_note_occurrences( - name='name_value', - filter='filter_value', - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].name - mock_val = 'name_value' - assert arg == mock_val - arg = args[0].filter - mock_val = 'filter_value' - assert arg == mock_val - -@pytest.mark.asyncio -async def test_list_note_occurrences_flattened_error_async(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.list_note_occurrences( - grafeas.ListNoteOccurrencesRequest(), - name='name_value', - filter='filter_value', - ) - - -def test_list_note_occurrences_pager(transport_name: str = "grpc"): - client = GrafeasClient( - 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_note_occurrences), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - next_page_token='abc', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[], - next_page_token='def', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - ], - next_page_token='ghi', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - ), - RuntimeError, - ) - - expected_metadata = () - retry = retries.Retry() - timeout = 5 - expected_metadata = tuple(expected_metadata) + ( - gapic_v1.routing_header.to_grpc_metadata(( - ('name', ''), - )), - ) - pager = client.list_note_occurrences(request={}, retry=retry, timeout=timeout) - - assert pager._metadata == expected_metadata - assert pager._retry == retry - assert pager._timeout == timeout - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, grafeas.Occurrence) - for i in results) -def test_list_note_occurrences_pages(transport_name: str = "grpc"): - client = GrafeasClient( - 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_note_occurrences), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - next_page_token='abc', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[], - next_page_token='def', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - ], - next_page_token='ghi', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - ), - RuntimeError, - ) - pages = list(client.list_note_occurrences(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_note_occurrences_async_pager(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_note_occurrences), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - next_page_token='abc', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[], - next_page_token='def', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - ], - next_page_token='ghi', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - ), - RuntimeError, - ) - async_pager = await client.list_note_occurrences(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, grafeas.Occurrence) - for i in responses) - - -@pytest.mark.asyncio -async def test_list_note_occurrences_async_pages(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_note_occurrences), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - next_page_token='abc', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[], - next_page_token='def', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - ], - next_page_token='ghi', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - ), - 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_note_occurrences(request={}) - ).pages: - pages.append(page_) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - - -def test_get_occurrence_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_occurrence in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.get_occurrence] = mock_rpc - - request = {} - client.get_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.get_occurrence(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_get_occurrence_rest_required_fields(request_type=grafeas.GetOccurrenceRequest): - transport_class = transports.GrafeasRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_occurrence._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_occurrence._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 = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.Occurrence() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "get", - 'query_params': pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.get_occurrence(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_get_occurrence_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.get_occurrence._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name", ))) - - -def test_get_occurrence_rest_flattened(): - client = GrafeasClient( - 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 = grafeas.Occurrence() - - # get arguments that satisfy an http rule for this method - sample_request = {'name': 'projects/sample1/occurrences/sample2'} - - # get truthy value for each flattened field - mock_args = dict( - name='name_value', - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.get_occurrence(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{name=projects/*/occurrences/*}" % client.transport._host, args[1]) - - -def test_get_occurrence_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - 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_occurrence( - grafeas.GetOccurrenceRequest(), - name='name_value', - ) - - -def test_list_occurrences_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_occurrences in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.list_occurrences] = mock_rpc - - request = {} - client.list_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_occurrences(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_list_occurrences_rest_required_fields(request_type=grafeas.ListOccurrencesRequest): - transport_class = transports.GrafeasRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_occurrences._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_occurrences._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 = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.ListOccurrencesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "get", - 'query_params': pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.ListOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.list_occurrences(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_list_occurrences_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.list_occurrences._get_unset_required_fields({}) - assert set(unset_fields) == (set(("filter", "pageSize", "pageToken", )) & set(("parent", ))) - - -def test_list_occurrences_rest_flattened(): - client = GrafeasClient( - 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 = grafeas.ListOccurrencesResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {'parent': 'projects/sample1'} - - # get truthy value for each flattened field - mock_args = dict( - parent='parent_value', - filter='filter_value', - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.ListOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.list_occurrences(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{parent=projects/*}/occurrences" % client.transport._host, args[1]) - - -def test_list_occurrences_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - 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_occurrences( - grafeas.ListOccurrencesRequest(), - parent='parent_value', - filter='filter_value', - ) - - -def test_list_occurrences_rest_pager(transport: str = 'rest'): - client = GrafeasClient( - 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 = ( - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - next_page_token='abc', - ), - grafeas.ListOccurrencesResponse( - occurrences=[], - next_page_token='def', - ), - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - ], - next_page_token='ghi', - ), - grafeas.ListOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(grafeas.ListOccurrencesResponse.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'} - - pager = client.list_occurrences(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, grafeas.Occurrence) - for i in results) - - pages = list(client.list_occurrences(request=sample_request).pages) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - - -def test_delete_occurrence_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.delete_occurrence in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.delete_occurrence] = mock_rpc - - request = {} - client.delete_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.delete_occurrence(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_delete_occurrence_rest_required_fields(request_type=grafeas.DeleteOccurrenceRequest): - transport_class = transports.GrafeasRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_occurrence._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_occurrence._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 = GrafeasClient( - 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_occurrence(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_delete_occurrence_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.delete_occurrence._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name", ))) - - -def test_delete_occurrence_rest_flattened(): - client = GrafeasClient( - 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/occurrences/sample2'} - - # 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_occurrence(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{name=projects/*/occurrences/*}" % client.transport._host, args[1]) - - -def test_delete_occurrence_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - 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_occurrence( - grafeas.DeleteOccurrenceRequest(), - name='name_value', - ) - - -def test_create_occurrence_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.create_occurrence in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.create_occurrence] = mock_rpc - - request = {} - client.create_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.create_occurrence(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_create_occurrence_rest_required_fields(request_type=grafeas.CreateOccurrenceRequest): - transport_class = transports.GrafeasRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_occurrence._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_occurrence._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 = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.Occurrence() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "post", - 'query_params': pb_request, - } - transcode_result['body'] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.create_occurrence(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_create_occurrence_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.create_occurrence._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("parent", "occurrence", ))) - - -def test_create_occurrence_rest_flattened(): - client = GrafeasClient( - 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 = grafeas.Occurrence() - - # get arguments that satisfy an http rule for this method - sample_request = {'parent': 'projects/sample1'} - - # get truthy value for each flattened field - mock_args = dict( - parent='parent_value', - occurrence=grafeas.Occurrence(name='name_value'), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.create_occurrence(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{parent=projects/*}/occurrences" % client.transport._host, args[1]) - - -def test_create_occurrence_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - 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_occurrence( - grafeas.CreateOccurrenceRequest(), - parent='parent_value', - occurrence=grafeas.Occurrence(name='name_value'), - ) - - -def test_batch_create_occurrences_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.batch_create_occurrences in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.batch_create_occurrences] = mock_rpc - - request = {} - client.batch_create_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.batch_create_occurrences(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_batch_create_occurrences_rest_required_fields(request_type=grafeas.BatchCreateOccurrencesRequest): - transport_class = transports.GrafeasRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_create_occurrences._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()).batch_create_occurrences._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 = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.BatchCreateOccurrencesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "post", - 'query_params': pb_request, - } - transcode_result['body'] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.BatchCreateOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.batch_create_occurrences(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_batch_create_occurrences_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.batch_create_occurrences._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("parent", "occurrences", ))) - - -def test_batch_create_occurrences_rest_flattened(): - client = GrafeasClient( - 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 = grafeas.BatchCreateOccurrencesResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {'parent': 'projects/sample1'} - - # get truthy value for each flattened field - mock_args = dict( - parent='parent_value', - occurrences=[grafeas.Occurrence(name='name_value')], - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.BatchCreateOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.batch_create_occurrences(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{parent=projects/*}/occurrences:batchCreate" % client.transport._host, args[1]) - - -def test_batch_create_occurrences_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.batch_create_occurrences( - grafeas.BatchCreateOccurrencesRequest(), - parent='parent_value', - occurrences=[grafeas.Occurrence(name='name_value')], - ) - - -def test_update_occurrence_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.update_occurrence in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.update_occurrence] = mock_rpc - - request = {} - client.update_occurrence(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.update_occurrence(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_update_occurrence_rest_required_fields(request_type=grafeas.UpdateOccurrenceRequest): - transport_class = transports.GrafeasRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_occurrence._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()).update_occurrence._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 - assert "name" in jsonified_request - assert jsonified_request["name"] == 'name_value' - - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.Occurrence() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "patch", - 'query_params': pb_request, - } - transcode_result['body'] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.update_occurrence(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_update_occurrence_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.update_occurrence._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask", )) & set(("name", "occurrence", ))) - - -def test_update_occurrence_rest_flattened(): - client = GrafeasClient( - 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 = grafeas.Occurrence() - - # get arguments that satisfy an http rule for this method - sample_request = {'name': 'projects/sample1/occurrences/sample2'} - - # get truthy value for each flattened field - mock_args = dict( - name='name_value', - occurrence=grafeas.Occurrence(name='name_value'), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.update_occurrence(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{name=projects/*/occurrences/*}" % client.transport._host, args[1]) - - -def test_update_occurrence_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - 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_occurrence( - grafeas.UpdateOccurrenceRequest(), - name='name_value', - occurrence=grafeas.Occurrence(name='name_value'), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - -def test_get_occurrence_note_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_occurrence_note in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.get_occurrence_note] = mock_rpc - - request = {} - client.get_occurrence_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.get_occurrence_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_get_occurrence_note_rest_required_fields(request_type=grafeas.GetOccurrenceNoteRequest): - transport_class = transports.GrafeasRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_occurrence_note._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_occurrence_note._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 = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.Note() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "get", - 'query_params': pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.get_occurrence_note(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_get_occurrence_note_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.get_occurrence_note._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name", ))) - - -def test_get_occurrence_note_rest_flattened(): - client = GrafeasClient( - 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 = grafeas.Note() - - # get arguments that satisfy an http rule for this method - sample_request = {'name': 'projects/sample1/occurrences/sample2'} - - # get truthy value for each flattened field - mock_args = dict( - name='name_value', - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.get_occurrence_note(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{name=projects/*/occurrences/*}/notes" % client.transport._host, args[1]) - - -def test_get_occurrence_note_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - 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_occurrence_note( - grafeas.GetOccurrenceNoteRequest(), - name='name_value', - ) - - -def test_get_note_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_note in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.get_note] = mock_rpc - - request = {} - client.get_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.get_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_get_note_rest_required_fields(request_type=grafeas.GetNoteRequest): - transport_class = transports.GrafeasRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).get_note._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_note._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 = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.Note() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "get", - 'query_params': pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.get_note(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_get_note_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.get_note._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name", ))) - - -def test_get_note_rest_flattened(): - client = GrafeasClient( - 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 = grafeas.Note() - - # get arguments that satisfy an http rule for this method - sample_request = {'name': 'projects/sample1/notes/sample2'} - - # get truthy value for each flattened field - mock_args = dict( - name='name_value', - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.get_note(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{name=projects/*/notes/*}" % client.transport._host, args[1]) - - -def test_get_note_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - 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_note( - grafeas.GetNoteRequest(), - name='name_value', - ) - - -def test_list_notes_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_notes in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.list_notes] = mock_rpc - - request = {} - client.list_notes(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_notes(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_list_notes_rest_required_fields(request_type=grafeas.ListNotesRequest): - transport_class = transports.GrafeasRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_notes._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_notes._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 = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.ListNotesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "get", - 'query_params': pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.ListNotesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.list_notes(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_list_notes_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.list_notes._get_unset_required_fields({}) - assert set(unset_fields) == (set(("filter", "pageSize", "pageToken", )) & set(("parent", ))) - - -def test_list_notes_rest_flattened(): - client = GrafeasClient( - 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 = grafeas.ListNotesResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {'parent': 'projects/sample1'} - - # get truthy value for each flattened field - mock_args = dict( - parent='parent_value', - filter='filter_value', - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.ListNotesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.list_notes(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{parent=projects/*}/notes" % client.transport._host, args[1]) - - -def test_list_notes_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - 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_notes( - grafeas.ListNotesRequest(), - parent='parent_value', - filter='filter_value', - ) - - -def test_list_notes_rest_pager(transport: str = 'rest'): - client = GrafeasClient( - 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 = ( - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - grafeas.Note(), - grafeas.Note(), - ], - next_page_token='abc', - ), - grafeas.ListNotesResponse( - notes=[], - next_page_token='def', - ), - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - ], - next_page_token='ghi', - ), - grafeas.ListNotesResponse( - notes=[ - grafeas.Note(), - grafeas.Note(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(grafeas.ListNotesResponse.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'} - - pager = client.list_notes(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, grafeas.Note) - for i in results) - - pages = list(client.list_notes(request=sample_request).pages) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - - -def test_delete_note_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.delete_note in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.delete_note] = mock_rpc - - request = {} - client.delete_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.delete_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_delete_note_rest_required_fields(request_type=grafeas.DeleteNoteRequest): - transport_class = transports.GrafeasRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).delete_note._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_note._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 = GrafeasClient( - 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_note(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_delete_note_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.delete_note._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name", ))) - - -def test_delete_note_rest_flattened(): - client = GrafeasClient( - 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/notes/sample2'} - - # 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_note(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{name=projects/*/notes/*}" % client.transport._host, args[1]) - - -def test_delete_note_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - 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_note( - grafeas.DeleteNoteRequest(), - name='name_value', - ) - - -def test_create_note_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.create_note in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.create_note] = mock_rpc - - request = {} - client.create_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.create_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_create_note_rest_required_fields(request_type=grafeas.CreateNoteRequest): - transport_class = transports.GrafeasRestTransport - - request_init = {} - request_init["parent"] = "" - request_init["note_id"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads(json_format.MessageToJson( - pb_request, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - assert "noteId" not in jsonified_request - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_note._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - assert "noteId" in jsonified_request - assert jsonified_request["noteId"] == request_init["note_id"] - - jsonified_request["parent"] = 'parent_value' - jsonified_request["noteId"] = 'note_id_value' - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_note._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("note_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 "noteId" in jsonified_request - assert jsonified_request["noteId"] == 'note_id_value' - - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.Note() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "post", - 'query_params': pb_request, - } - transcode_result['body'] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.create_note(request) - - expected_params = [ - ( - "noteId", - "", - ), - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_create_note_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.create_note._get_unset_required_fields({}) - assert set(unset_fields) == (set(("noteId", )) & set(("parent", "noteId", "note", ))) - - -def test_create_note_rest_flattened(): - client = GrafeasClient( - 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 = grafeas.Note() - - # get arguments that satisfy an http rule for this method - sample_request = {'parent': 'projects/sample1'} - - # get truthy value for each flattened field - mock_args = dict( - parent='parent_value', - note_id='note_id_value', - note=grafeas.Note(name='name_value'), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.create_note(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{parent=projects/*}/notes" % client.transport._host, args[1]) - - -def test_create_note_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - 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_note( - grafeas.CreateNoteRequest(), - parent='parent_value', - note_id='note_id_value', - note=grafeas.Note(name='name_value'), - ) - - -def test_batch_create_notes_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.batch_create_notes in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.batch_create_notes] = mock_rpc - - request = {} - client.batch_create_notes(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.batch_create_notes(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_batch_create_notes_rest_required_fields(request_type=grafeas.BatchCreateNotesRequest): - transport_class = transports.GrafeasRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_create_notes._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()).batch_create_notes._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 = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.BatchCreateNotesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "post", - 'query_params': pb_request, - } - transcode_result['body'] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.BatchCreateNotesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.batch_create_notes(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_batch_create_notes_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.batch_create_notes._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("parent", "notes", ))) - - -def test_batch_create_notes_rest_flattened(): - client = GrafeasClient( - 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 = grafeas.BatchCreateNotesResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {'parent': 'projects/sample1'} - - # get truthy value for each flattened field - mock_args = dict( - parent='parent_value', - notes={'key_value': grafeas.Note(name='name_value')}, - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.BatchCreateNotesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.batch_create_notes(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{parent=projects/*}/notes:batchCreate" % client.transport._host, args[1]) - - -def test_batch_create_notes_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.batch_create_notes( - grafeas.BatchCreateNotesRequest(), - parent='parent_value', - notes={'key_value': grafeas.Note(name='name_value')}, - ) - - -def test_update_note_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.update_note in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.update_note] = mock_rpc - - request = {} - client.update_note(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.update_note(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_update_note_rest_required_fields(request_type=grafeas.UpdateNoteRequest): - transport_class = transports.GrafeasRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).update_note._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()).update_note._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 - assert "name" in jsonified_request - assert jsonified_request["name"] == 'name_value' - - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.Note() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "patch", - 'query_params': pb_request, - } - transcode_result['body'] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.update_note(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_update_note_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.update_note._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask", )) & set(("name", "note", ))) - - -def test_update_note_rest_flattened(): - client = GrafeasClient( - 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 = grafeas.Note() - - # get arguments that satisfy an http rule for this method - sample_request = {'name': 'projects/sample1/notes/sample2'} - - # get truthy value for each flattened field - mock_args = dict( - name='name_value', - note=grafeas.Note(name='name_value'), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.update_note(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{name=projects/*/notes/*}" % client.transport._host, args[1]) - - -def test_update_note_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - 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_note( - grafeas.UpdateNoteRequest(), - name='name_value', - note=grafeas.Note(name='name_value'), - update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), - ) - - -def test_list_note_occurrences_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_note_occurrences in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.list_note_occurrences] = mock_rpc - - request = {} - client.list_note_occurrences(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_note_occurrences(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_list_note_occurrences_rest_required_fields(request_type=grafeas.ListNoteOccurrencesRequest): - transport_class = transports.GrafeasRestTransport - - 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, - use_integers_for_enums=False - )) - - # verify fields with default values are dropped - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_note_occurrences._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = 'name_value' - - unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).list_note_occurrences._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 "name" in jsonified_request - assert jsonified_request["name"] == 'name_value' - - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest', - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = grafeas.ListNoteOccurrencesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, 'request') as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, 'transcode') as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - 'uri': 'v1/sample_method', - 'method': "get", - 'query_params': pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.ListNoteOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - response = client.list_note_occurrences(request) - - expected_params = [ - ('$alt', 'json;enum-encoding=int') - ] - actual_params = req.call_args.kwargs['params'] - assert expected_params == actual_params - - -def test_list_note_occurrences_rest_unset_required_fields(): - transport = transports.GrafeasRestTransport(credentials=ga_credentials.AnonymousCredentials) - - unset_fields = transport.list_note_occurrences._get_unset_required_fields({}) - assert set(unset_fields) == (set(("filter", "pageSize", "pageToken", )) & set(("name", ))) - - -def test_list_note_occurrences_rest_flattened(): - client = GrafeasClient( - 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 = grafeas.ListNoteOccurrencesResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {'name': 'projects/sample1/notes/sample2'} - - # get truthy value for each flattened field - mock_args = dict( - name='name_value', - filter='filter_value', - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = grafeas.ListNoteOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode('UTF-8') - req.return_value = response_value - - client.list_note_occurrences(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate("%s/v1/{name=projects/*/notes/*}/occurrences" % client.transport._host, args[1]) - - -def test_list_note_occurrences_rest_flattened_error(transport: str = 'rest'): - client = GrafeasClient( - 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_note_occurrences( - grafeas.ListNoteOccurrencesRequest(), - name='name_value', - filter='filter_value', - ) - - -def test_list_note_occurrences_rest_pager(transport: str = 'rest'): - client = GrafeasClient( - 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 = ( - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - next_page_token='abc', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[], - next_page_token='def', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - ], - next_page_token='ghi', - ), - grafeas.ListNoteOccurrencesResponse( - occurrences=[ - grafeas.Occurrence(), - grafeas.Occurrence(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(grafeas.ListNoteOccurrencesResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode('UTF-8') - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {'name': 'projects/sample1/notes/sample2'} - - pager = client.list_note_occurrences(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, grafeas.Occurrence) - for i in results) - - pages = list(client.list_note_occurrences(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.GrafeasGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.GrafeasGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = GrafeasClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.GrafeasGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = GrafeasClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = GrafeasClient( - client_options=options, - credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.GrafeasGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = GrafeasClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.GrafeasGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = GrafeasClient(transport=transport) - assert client.transport is transport - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.GrafeasGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.GrafeasGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize("transport_class", [ - transports.GrafeasGrpcTransport, - transports.GrafeasGrpcAsyncIOTransport, - transports.GrafeasRestTransport, -]) -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() - -def test_transport_kind_grpc(): - transport = GrafeasClient.get_transport_class("grpc")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "grpc" - - -def test_initialize_client_w_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_occurrence_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence), - '__call__') as call: - call.return_value = grafeas.Occurrence() - client.get_occurrence(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.GetOccurrenceRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_occurrences_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_occurrences), - '__call__') as call: - call.return_value = grafeas.ListOccurrencesResponse() - client.list_occurrences(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.ListOccurrencesRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_occurrence_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_occurrence), - '__call__') as call: - call.return_value = None - client.delete_occurrence(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.DeleteOccurrenceRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_occurrence_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_occurrence), - '__call__') as call: - call.return_value = grafeas.Occurrence() - client.create_occurrence(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.CreateOccurrenceRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_batch_create_occurrences_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_occurrences), - '__call__') as call: - call.return_value = grafeas.BatchCreateOccurrencesResponse() - client.batch_create_occurrences(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.BatchCreateOccurrencesRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_occurrence_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_occurrence), - '__call__') as call: - call.return_value = grafeas.Occurrence() - client.update_occurrence(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.UpdateOccurrenceRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_occurrence_note_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence_note), - '__call__') as call: - call.return_value = grafeas.Note() - client.get_occurrence_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.GetOccurrenceNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_note_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_note), - '__call__') as call: - call.return_value = grafeas.Note() - client.get_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.GetNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_notes_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_notes), - '__call__') as call: - call.return_value = grafeas.ListNotesResponse() - client.list_notes(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.ListNotesRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_note_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_note), - '__call__') as call: - call.return_value = None - client.delete_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.DeleteNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_note_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_note), - '__call__') as call: - call.return_value = grafeas.Note() - client.create_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.CreateNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_batch_create_notes_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_notes), - '__call__') as call: - call.return_value = grafeas.BatchCreateNotesResponse() - client.batch_create_notes(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.BatchCreateNotesRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_note_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_note), - '__call__') as call: - call.return_value = grafeas.Note() - client.update_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.UpdateNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_note_occurrences_empty_call_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_note_occurrences), - '__call__') as call: - call.return_value = grafeas.ListNoteOccurrencesResponse() - client.list_note_occurrences(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.ListNoteOccurrencesRequest() - - assert args[0] == request_msg - - -def test_transport_kind_grpc_asyncio(): - transport = GrafeasAsyncClient.get_transport_class("grpc_asyncio")( - credentials=async_anonymous_credentials() - ) - assert transport.kind == "grpc_asyncio" - - -def test_initialize_client_w_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_occurrence_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence( - name='name_value', - resource_uri='resource_uri_value', - note_name='note_name_value', - kind=common.NoteKind.VULNERABILITY, - remediation='remediation_value', - )) - await client.get_occurrence(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.GetOccurrenceRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_occurrences_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListOccurrencesResponse( - next_page_token='next_page_token_value', - )) - await client.list_occurrences(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.ListOccurrencesRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_occurrence_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - await client.delete_occurrence(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.DeleteOccurrenceRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_occurrence_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence( - name='name_value', - resource_uri='resource_uri_value', - note_name='note_name_value', - kind=common.NoteKind.VULNERABILITY, - remediation='remediation_value', - )) - await client.create_occurrence(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.CreateOccurrenceRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_batch_create_occurrences_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateOccurrencesResponse( - )) - await client.batch_create_occurrences(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.BatchCreateOccurrencesRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_occurrence_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_occurrence), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Occurrence( - name='name_value', - resource_uri='resource_uri_value', - note_name='note_name_value', - kind=common.NoteKind.VULNERABILITY, - remediation='remediation_value', - )) - await client.update_occurrence(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.UpdateOccurrenceRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_occurrence_note_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - )) - await client.get_occurrence_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.GetOccurrenceNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_note_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - )) - await client.get_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.GetNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_notes_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_notes), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNotesResponse( - next_page_token='next_page_token_value', - )) - await client.list_notes(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.ListNotesRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_note_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) - await client.delete_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.DeleteNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_create_note_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - )) - await client.create_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.CreateNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_batch_create_notes_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_notes), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.BatchCreateNotesResponse( - )) - await client.batch_create_notes(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.BatchCreateNotesRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_note_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_note), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - )) - await client.update_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.UpdateNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_note_occurrences_empty_call_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_note_occurrences), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(grafeas.ListNoteOccurrencesResponse( - next_page_token='next_page_token_value', - )) - await client.list_note_occurrences(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.ListNoteOccurrencesRequest() - - assert args[0] == request_msg - - -def test_transport_kind_rest(): - transport = GrafeasClient.get_transport_class("rest")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "rest" - - -def test_get_occurrence_rest_bad_request(request_type=grafeas.GetOccurrenceRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/occurrences/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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.get_occurrence(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.GetOccurrenceRequest, - dict, -]) -def test_get_occurrence_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/occurrences/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 = grafeas.Occurrence( - name='name_value', - resource_uri='resource_uri_value', - note_name='note_name_value', - kind=common.NoteKind.VULNERABILITY, - remediation='remediation_value', - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.get_occurrence(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Occurrence) - assert response.name == 'name_value' - assert response.resource_uri == 'resource_uri_value' - assert response.note_name == 'note_name_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.remediation == 'remediation_value' - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_occurrence_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "post_get_occurrence") as post, \ - mock.patch.object(transports.GrafeasRestInterceptor, "pre_get_occurrence") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.GetOccurrenceRequest.pb(grafeas.GetOccurrenceRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = grafeas.Occurrence.to_json(grafeas.Occurrence()) - req.return_value.content = return_value - - request = grafeas.GetOccurrenceRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.Occurrence() - - client.get_occurrence(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_occurrences_rest_bad_request(request_type=grafeas.ListOccurrencesRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'parent': 'projects/sample1'} - 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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.list_occurrences(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.ListOccurrencesRequest, - dict, -]) -def test_list_occurrences_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'parent': 'projects/sample1'} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), 'request') as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.ListOccurrencesResponse( - next_page_token='next_page_token_value', - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.ListOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.list_occurrences(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListOccurrencesPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_occurrences_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "post_list_occurrences") as post, \ - mock.patch.object(transports.GrafeasRestInterceptor, "pre_list_occurrences") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.ListOccurrencesRequest.pb(grafeas.ListOccurrencesRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = grafeas.ListOccurrencesResponse.to_json(grafeas.ListOccurrencesResponse()) - req.return_value.content = return_value - - request = grafeas.ListOccurrencesRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.ListOccurrencesResponse() - - client.list_occurrences(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - - -def test_delete_occurrence_rest_bad_request(request_type=grafeas.DeleteOccurrenceRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/occurrences/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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.delete_occurrence(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.DeleteOccurrenceRequest, - dict, -]) -def test_delete_occurrence_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/occurrences/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 = None - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - 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_occurrence(request) - - # Establish that the response is the type that we expect. - assert response is None - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_occurrence_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "pre_delete_occurrence") as pre: - pre.assert_not_called() - pb_message = grafeas.DeleteOccurrenceRequest.pb(grafeas.DeleteOccurrenceRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - - request = grafeas.DeleteOccurrenceRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - - client.delete_occurrence(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - - -def test_create_occurrence_rest_bad_request(request_type=grafeas.CreateOccurrenceRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'parent': 'projects/sample1'} - 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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.create_occurrence(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.CreateOccurrenceRequest, - dict, -]) -def test_create_occurrence_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'parent': 'projects/sample1'} - request_init["occurrence"] = {'name': 'name_value', 'resource_uri': 'resource_uri_value', 'note_name': 'note_name_value', 'kind': 1, 'remediation': 'remediation_value', 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'vulnerability': {'type_': 'type__value', 'severity': 1, 'cvss_score': 0.1082, 'cvssv3': {'base_score': 0.1046, 'exploitability_score': 0.21580000000000002, 'impact_score': 0.1273, 'attack_vector': 1, 'attack_complexity': 1, 'authentication': 1, 'privileges_required': 1, 'user_interaction': 1, 'scope': 1, 'confidentiality_impact': 1, 'integrity_impact': 1, 'availability_impact': 1}, 'package_issue': [{'affected_cpe_uri': 'affected_cpe_uri_value', 'affected_package': 'affected_package_value', 'affected_version': {'epoch': 527, 'name': 'name_value', 'revision': 'revision_value', 'inclusive': True, 'kind': 1, 'full_name': 'full_name_value'}, 'fixed_cpe_uri': 'fixed_cpe_uri_value', 'fixed_package': 'fixed_package_value', 'fixed_version': {}, 'fix_available': True, 'package_type': 'package_type_value', 'effective_severity': 1, 'file_location': [{'file_path': 'file_path_value'}]}], 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'related_urls': [{'url': 'url_value', 'label': 'label_value'}], 'effective_severity': 1, 'fix_available': True, 'cvss_version': 1, 'cvss_v2': {}, 'vex_assessment': {'cve': 'cve_value', 'vulnerability_id': 'vulnerability_id_value', 'related_uris': {}, 'note_name': 'note_name_value', 'state': 1, 'impacts': ['impacts_value1', 'impacts_value2'], 'remediations': [{'remediation_type': 1, 'details': 'details_value', 'remediation_uri': {}}], 'justification': {'justification_type': 1, 'details': 'details_value'}}, 'extra_details': 'extra_details_value'}, 'build': {'provenance': {'id': 'id_value', 'project_id': 'project_id_value', 'commands': [{'name': 'name_value', 'env': ['env_value1', 'env_value2'], 'args': ['args_value1', 'args_value2'], 'dir_': 'dir__value', 'id': 'id_value', 'wait_for': ['wait_for_value1', 'wait_for_value2']}], 'built_artifacts': [{'checksum': 'checksum_value', 'id': 'id_value', 'names': ['names_value1', 'names_value2']}], 'create_time': {}, 'start_time': {}, 'end_time': {}, 'creator': 'creator_value', 'logs_uri': 'logs_uri_value', 'source_provenance': {'artifact_storage_source_uri': 'artifact_storage_source_uri_value', 'file_hashes': {}, 'context': {'cloud_repo': {'repo_id': {'project_repo_id': {'project_id': 'project_id_value', 'repo_name': 'repo_name_value'}, 'uid': 'uid_value'}, 'revision_id': 'revision_id_value', 'alias_context': {'kind': 1, 'name': 'name_value'}}, 'gerrit': {'host_uri': 'host_uri_value', 'gerrit_project': 'gerrit_project_value', 'revision_id': 'revision_id_value', 'alias_context': {}}, 'git': {'url': 'url_value', 'revision_id': 'revision_id_value'}, 'labels': {}}, 'additional_contexts': {}}, 'trigger_id': 'trigger_id_value', 'build_options': {}, 'builder_version': 'builder_version_value'}, 'provenance_bytes': 'provenance_bytes_value', 'intoto_provenance': {'builder_config': {'id': 'id_value'}, 'recipe': {'type_': 'type__value', 'defined_in_material': 1971, 'entry_point': 'entry_point_value', 'arguments': [{'type_url': 'type.googleapis.com/google.protobuf.Duration', 'value': b'\x08\x0c\x10\xdb\x07'}], 'environment': {}}, 'metadata': {'build_invocation_id': 'build_invocation_id_value', 'build_started_on': {}, 'build_finished_on': {}, 'completeness': {'arguments': True, 'environment': True, 'materials': True}, 'reproducible': True}, 'materials': ['materials_value1', 'materials_value2']}, 'intoto_statement': {'type_': 'type__value', 'subject': [{'name': 'name_value', 'digest': {}}], 'predicate_type': 'predicate_type_value', 'provenance': {}, 'slsa_provenance': {'builder': {'id': 'id_value'}, 'recipe': {'type_': 'type__value', 'defined_in_material': 1971, 'entry_point': 'entry_point_value', 'arguments': {}, 'environment': {}}, 'metadata': {'build_invocation_id': 'build_invocation_id_value', 'build_started_on': {}, 'build_finished_on': {}, 'completeness': {'arguments': True, 'environment': True, 'materials': True}, 'reproducible': True}, 'materials': [{'uri': 'uri_value', 'digest': {}}]}, 'slsa_provenance_zero_two': {'builder': {'id': 'id_value'}, 'build_type': 'build_type_value', 'invocation': {'config_source': {'uri': 'uri_value', 'digest': {}, 'entry_point': 'entry_point_value'}, 'parameters': {'fields': {}}, 'environment': {}}, 'build_config': {}, 'metadata': {'build_invocation_id': 'build_invocation_id_value', 'build_started_on': {}, 'build_finished_on': {}, 'completeness': {'parameters': True, 'environment': True, 'materials': True}, 'reproducible': True}, 'materials': [{'uri': 'uri_value', 'digest': {}}]}}, 'in_toto_slsa_provenance_v1': {'type_': 'type__value', 'subject': {}, 'predicate_type': 'predicate_type_value', 'predicate': {'build_definition': {'build_type': 'build_type_value', 'external_parameters': {}, 'internal_parameters': {}, 'resolved_dependencies': [{'name': 'name_value', 'uri': 'uri_value', 'digest': {}, 'content': b'content_blob', 'download_location': 'download_location_value', 'media_type': 'media_type_value', 'annotations': {}}]}, 'run_details': {'builder': {'id': 'id_value', 'version': {}, 'builder_dependencies': {}}, 'metadata': {'invocation_id': 'invocation_id_value', 'started_on': {}, 'finished_on': {}}, 'byproducts': {}}}}}, 'image': {'fingerprint': {'v1_name': 'v1_name_value', 'v2_blob': ['v2_blob_value1', 'v2_blob_value2'], 'v2_name': 'v2_name_value'}, 'distance': 843, 'layer_info': [{'directive': 'directive_value', 'arguments': 'arguments_value'}], 'base_resource_url': 'base_resource_url_value'}, 'package': {'name': 'name_value', 'location': [{'cpe_uri': 'cpe_uri_value', 'version': {}, 'path': 'path_value'}], 'package_type': 'package_type_value', 'cpe_uri': 'cpe_uri_value', 'architecture': 1, 'license_': {'expression': 'expression_value', 'comments': 'comments_value'}, 'version': {}}, 'deployment': {'user_email': 'user_email_value', 'deploy_time': {}, 'undeploy_time': {}, 'config': 'config_value', 'address': 'address_value', 'resource_uri': ['resource_uri_value1', 'resource_uri_value2'], 'platform': 1}, 'discovery': {'continuous_analysis': 1, 'analysis_status': 1, 'analysis_completed': {'analysis_type': ['analysis_type_value1', 'analysis_type_value2']}, 'analysis_error': [{'code': 411, 'message': 'message_value', 'details': {}}], 'analysis_status_error': {}, 'cpe': 'cpe_value', 'last_scan_time': {}, 'archive_time': {}, 'sbom_status': {'sbom_state': 1, 'error': 'error_value'}, 'vulnerability_attestation': {'last_attempt_time': {}, 'state': 1, 'error': 'error_value'}}, 'attestation': {'serialized_payload': b'serialized_payload_blob', 'signatures': [{'signature': b'signature_blob', 'public_key_id': 'public_key_id_value'}], 'jwts': [{'compact_jwt': 'compact_jwt_value'}]}, 'upgrade': {'package': 'package_value', 'parsed_version': {}, 'distribution': {'cpe_uri': 'cpe_uri_value', 'classification': 'classification_value', 'severity': 'severity_value', 'cve': ['cve_value1', 'cve_value2']}, 'windows_update': {'identity': {'update_id': 'update_id_value', 'revision': 879}, 'title': 'title_value', 'description': 'description_value', 'categories': [{'category_id': 'category_id_value', 'name': 'name_value'}], 'kb_article_ids': ['kb_article_ids_value1', 'kb_article_ids_value2'], 'support_url': 'support_url_value', 'last_published_timestamp': {}}}, 'compliance': {'non_compliant_files': [{'path': 'path_value', 'display_command': 'display_command_value', 'reason': 'reason_value'}], 'non_compliance_reason': 'non_compliance_reason_value', 'version': {'cpe_uri': 'cpe_uri_value', 'benchmark_document': 'benchmark_document_value', 'version': 'version_value'}}, 'dsse_attestation': {'envelope': {'payload': b'payload_blob', 'payload_type': 'payload_type_value', 'signatures': [{'sig': b'sig_blob', 'keyid': 'keyid_value'}]}, 'statement': {}}, 'sbom_reference': {'payload': {'type_': 'type__value', 'predicate_type': 'predicate_type_value', 'subject': {}, 'predicate': {'referrer_id': 'referrer_id_value', 'location': 'location_value', 'mime_type': 'mime_type_value', 'digest': {}}}, 'payload_type': 'payload_type_value', 'signatures': {}}, 'envelope': {}} - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = grafeas.CreateOccurrenceRequest.meta.fields["occurrence"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["occurrence"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - {"field": field, "subfield": subfield, "is_repeated": is_repeated} - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["occurrence"][field])): - del request_init["occurrence"][field][i][subfield] - else: - del request_init["occurrence"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), 'request') as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.Occurrence( - name='name_value', - resource_uri='resource_uri_value', - note_name='note_name_value', - kind=common.NoteKind.VULNERABILITY, - remediation='remediation_value', - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.create_occurrence(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Occurrence) - assert response.name == 'name_value' - assert response.resource_uri == 'resource_uri_value' - assert response.note_name == 'note_name_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.remediation == 'remediation_value' - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_occurrence_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "post_create_occurrence") as post, \ - mock.patch.object(transports.GrafeasRestInterceptor, "pre_create_occurrence") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.CreateOccurrenceRequest.pb(grafeas.CreateOccurrenceRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = grafeas.Occurrence.to_json(grafeas.Occurrence()) - req.return_value.content = return_value - - request = grafeas.CreateOccurrenceRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.Occurrence() - - client.create_occurrence(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - - -def test_batch_create_occurrences_rest_bad_request(request_type=grafeas.BatchCreateOccurrencesRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'parent': 'projects/sample1'} - 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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.batch_create_occurrences(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.BatchCreateOccurrencesRequest, - dict, -]) -def test_batch_create_occurrences_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'parent': 'projects/sample1'} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), 'request') as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.BatchCreateOccurrencesResponse( - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.BatchCreateOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.batch_create_occurrences(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.BatchCreateOccurrencesResponse) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_batch_create_occurrences_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "post_batch_create_occurrences") as post, \ - mock.patch.object(transports.GrafeasRestInterceptor, "pre_batch_create_occurrences") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.BatchCreateOccurrencesRequest.pb(grafeas.BatchCreateOccurrencesRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = grafeas.BatchCreateOccurrencesResponse.to_json(grafeas.BatchCreateOccurrencesResponse()) - req.return_value.content = return_value - - request = grafeas.BatchCreateOccurrencesRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.BatchCreateOccurrencesResponse() - - client.batch_create_occurrences(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_occurrence_rest_bad_request(request_type=grafeas.UpdateOccurrenceRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/occurrences/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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.update_occurrence(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.UpdateOccurrenceRequest, - dict, -]) -def test_update_occurrence_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/occurrences/sample2'} - request_init["occurrence"] = {'name': 'name_value', 'resource_uri': 'resource_uri_value', 'note_name': 'note_name_value', 'kind': 1, 'remediation': 'remediation_value', 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'vulnerability': {'type_': 'type__value', 'severity': 1, 'cvss_score': 0.1082, 'cvssv3': {'base_score': 0.1046, 'exploitability_score': 0.21580000000000002, 'impact_score': 0.1273, 'attack_vector': 1, 'attack_complexity': 1, 'authentication': 1, 'privileges_required': 1, 'user_interaction': 1, 'scope': 1, 'confidentiality_impact': 1, 'integrity_impact': 1, 'availability_impact': 1}, 'package_issue': [{'affected_cpe_uri': 'affected_cpe_uri_value', 'affected_package': 'affected_package_value', 'affected_version': {'epoch': 527, 'name': 'name_value', 'revision': 'revision_value', 'inclusive': True, 'kind': 1, 'full_name': 'full_name_value'}, 'fixed_cpe_uri': 'fixed_cpe_uri_value', 'fixed_package': 'fixed_package_value', 'fixed_version': {}, 'fix_available': True, 'package_type': 'package_type_value', 'effective_severity': 1, 'file_location': [{'file_path': 'file_path_value'}]}], 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'related_urls': [{'url': 'url_value', 'label': 'label_value'}], 'effective_severity': 1, 'fix_available': True, 'cvss_version': 1, 'cvss_v2': {}, 'vex_assessment': {'cve': 'cve_value', 'vulnerability_id': 'vulnerability_id_value', 'related_uris': {}, 'note_name': 'note_name_value', 'state': 1, 'impacts': ['impacts_value1', 'impacts_value2'], 'remediations': [{'remediation_type': 1, 'details': 'details_value', 'remediation_uri': {}}], 'justification': {'justification_type': 1, 'details': 'details_value'}}, 'extra_details': 'extra_details_value'}, 'build': {'provenance': {'id': 'id_value', 'project_id': 'project_id_value', 'commands': [{'name': 'name_value', 'env': ['env_value1', 'env_value2'], 'args': ['args_value1', 'args_value2'], 'dir_': 'dir__value', 'id': 'id_value', 'wait_for': ['wait_for_value1', 'wait_for_value2']}], 'built_artifacts': [{'checksum': 'checksum_value', 'id': 'id_value', 'names': ['names_value1', 'names_value2']}], 'create_time': {}, 'start_time': {}, 'end_time': {}, 'creator': 'creator_value', 'logs_uri': 'logs_uri_value', 'source_provenance': {'artifact_storage_source_uri': 'artifact_storage_source_uri_value', 'file_hashes': {}, 'context': {'cloud_repo': {'repo_id': {'project_repo_id': {'project_id': 'project_id_value', 'repo_name': 'repo_name_value'}, 'uid': 'uid_value'}, 'revision_id': 'revision_id_value', 'alias_context': {'kind': 1, 'name': 'name_value'}}, 'gerrit': {'host_uri': 'host_uri_value', 'gerrit_project': 'gerrit_project_value', 'revision_id': 'revision_id_value', 'alias_context': {}}, 'git': {'url': 'url_value', 'revision_id': 'revision_id_value'}, 'labels': {}}, 'additional_contexts': {}}, 'trigger_id': 'trigger_id_value', 'build_options': {}, 'builder_version': 'builder_version_value'}, 'provenance_bytes': 'provenance_bytes_value', 'intoto_provenance': {'builder_config': {'id': 'id_value'}, 'recipe': {'type_': 'type__value', 'defined_in_material': 1971, 'entry_point': 'entry_point_value', 'arguments': [{'type_url': 'type.googleapis.com/google.protobuf.Duration', 'value': b'\x08\x0c\x10\xdb\x07'}], 'environment': {}}, 'metadata': {'build_invocation_id': 'build_invocation_id_value', 'build_started_on': {}, 'build_finished_on': {}, 'completeness': {'arguments': True, 'environment': True, 'materials': True}, 'reproducible': True}, 'materials': ['materials_value1', 'materials_value2']}, 'intoto_statement': {'type_': 'type__value', 'subject': [{'name': 'name_value', 'digest': {}}], 'predicate_type': 'predicate_type_value', 'provenance': {}, 'slsa_provenance': {'builder': {'id': 'id_value'}, 'recipe': {'type_': 'type__value', 'defined_in_material': 1971, 'entry_point': 'entry_point_value', 'arguments': {}, 'environment': {}}, 'metadata': {'build_invocation_id': 'build_invocation_id_value', 'build_started_on': {}, 'build_finished_on': {}, 'completeness': {'arguments': True, 'environment': True, 'materials': True}, 'reproducible': True}, 'materials': [{'uri': 'uri_value', 'digest': {}}]}, 'slsa_provenance_zero_two': {'builder': {'id': 'id_value'}, 'build_type': 'build_type_value', 'invocation': {'config_source': {'uri': 'uri_value', 'digest': {}, 'entry_point': 'entry_point_value'}, 'parameters': {'fields': {}}, 'environment': {}}, 'build_config': {}, 'metadata': {'build_invocation_id': 'build_invocation_id_value', 'build_started_on': {}, 'build_finished_on': {}, 'completeness': {'parameters': True, 'environment': True, 'materials': True}, 'reproducible': True}, 'materials': [{'uri': 'uri_value', 'digest': {}}]}}, 'in_toto_slsa_provenance_v1': {'type_': 'type__value', 'subject': {}, 'predicate_type': 'predicate_type_value', 'predicate': {'build_definition': {'build_type': 'build_type_value', 'external_parameters': {}, 'internal_parameters': {}, 'resolved_dependencies': [{'name': 'name_value', 'uri': 'uri_value', 'digest': {}, 'content': b'content_blob', 'download_location': 'download_location_value', 'media_type': 'media_type_value', 'annotations': {}}]}, 'run_details': {'builder': {'id': 'id_value', 'version': {}, 'builder_dependencies': {}}, 'metadata': {'invocation_id': 'invocation_id_value', 'started_on': {}, 'finished_on': {}}, 'byproducts': {}}}}}, 'image': {'fingerprint': {'v1_name': 'v1_name_value', 'v2_blob': ['v2_blob_value1', 'v2_blob_value2'], 'v2_name': 'v2_name_value'}, 'distance': 843, 'layer_info': [{'directive': 'directive_value', 'arguments': 'arguments_value'}], 'base_resource_url': 'base_resource_url_value'}, 'package': {'name': 'name_value', 'location': [{'cpe_uri': 'cpe_uri_value', 'version': {}, 'path': 'path_value'}], 'package_type': 'package_type_value', 'cpe_uri': 'cpe_uri_value', 'architecture': 1, 'license_': {'expression': 'expression_value', 'comments': 'comments_value'}, 'version': {}}, 'deployment': {'user_email': 'user_email_value', 'deploy_time': {}, 'undeploy_time': {}, 'config': 'config_value', 'address': 'address_value', 'resource_uri': ['resource_uri_value1', 'resource_uri_value2'], 'platform': 1}, 'discovery': {'continuous_analysis': 1, 'analysis_status': 1, 'analysis_completed': {'analysis_type': ['analysis_type_value1', 'analysis_type_value2']}, 'analysis_error': [{'code': 411, 'message': 'message_value', 'details': {}}], 'analysis_status_error': {}, 'cpe': 'cpe_value', 'last_scan_time': {}, 'archive_time': {}, 'sbom_status': {'sbom_state': 1, 'error': 'error_value'}, 'vulnerability_attestation': {'last_attempt_time': {}, 'state': 1, 'error': 'error_value'}}, 'attestation': {'serialized_payload': b'serialized_payload_blob', 'signatures': [{'signature': b'signature_blob', 'public_key_id': 'public_key_id_value'}], 'jwts': [{'compact_jwt': 'compact_jwt_value'}]}, 'upgrade': {'package': 'package_value', 'parsed_version': {}, 'distribution': {'cpe_uri': 'cpe_uri_value', 'classification': 'classification_value', 'severity': 'severity_value', 'cve': ['cve_value1', 'cve_value2']}, 'windows_update': {'identity': {'update_id': 'update_id_value', 'revision': 879}, 'title': 'title_value', 'description': 'description_value', 'categories': [{'category_id': 'category_id_value', 'name': 'name_value'}], 'kb_article_ids': ['kb_article_ids_value1', 'kb_article_ids_value2'], 'support_url': 'support_url_value', 'last_published_timestamp': {}}}, 'compliance': {'non_compliant_files': [{'path': 'path_value', 'display_command': 'display_command_value', 'reason': 'reason_value'}], 'non_compliance_reason': 'non_compliance_reason_value', 'version': {'cpe_uri': 'cpe_uri_value', 'benchmark_document': 'benchmark_document_value', 'version': 'version_value'}}, 'dsse_attestation': {'envelope': {'payload': b'payload_blob', 'payload_type': 'payload_type_value', 'signatures': [{'sig': b'sig_blob', 'keyid': 'keyid_value'}]}, 'statement': {}}, 'sbom_reference': {'payload': {'type_': 'type__value', 'predicate_type': 'predicate_type_value', 'subject': {}, 'predicate': {'referrer_id': 'referrer_id_value', 'location': 'location_value', 'mime_type': 'mime_type_value', 'digest': {}}}, 'payload_type': 'payload_type_value', 'signatures': {}}, 'envelope': {}} - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = grafeas.UpdateOccurrenceRequest.meta.fields["occurrence"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["occurrence"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - {"field": field, "subfield": subfield, "is_repeated": is_repeated} - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["occurrence"][field])): - del request_init["occurrence"][field][i][subfield] - else: - del request_init["occurrence"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), 'request') as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.Occurrence( - name='name_value', - resource_uri='resource_uri_value', - note_name='note_name_value', - kind=common.NoteKind.VULNERABILITY, - remediation='remediation_value', - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Occurrence.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.update_occurrence(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Occurrence) - assert response.name == 'name_value' - assert response.resource_uri == 'resource_uri_value' - assert response.note_name == 'note_name_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.remediation == 'remediation_value' - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_occurrence_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "post_update_occurrence") as post, \ - mock.patch.object(transports.GrafeasRestInterceptor, "pre_update_occurrence") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.UpdateOccurrenceRequest.pb(grafeas.UpdateOccurrenceRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = grafeas.Occurrence.to_json(grafeas.Occurrence()) - req.return_value.content = return_value - - request = grafeas.UpdateOccurrenceRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.Occurrence() - - client.update_occurrence(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_occurrence_note_rest_bad_request(request_type=grafeas.GetOccurrenceNoteRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/occurrences/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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.get_occurrence_note(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.GetOccurrenceNoteRequest, - dict, -]) -def test_get_occurrence_note_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/occurrences/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 = grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.get_occurrence_note(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == 'name_value' - assert response.short_description == 'short_description_value' - assert response.long_description == 'long_description_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ['related_note_names_value'] - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_occurrence_note_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "post_get_occurrence_note") as post, \ - mock.patch.object(transports.GrafeasRestInterceptor, "pre_get_occurrence_note") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.GetOccurrenceNoteRequest.pb(grafeas.GetOccurrenceNoteRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = grafeas.Note.to_json(grafeas.Note()) - req.return_value.content = return_value - - request = grafeas.GetOccurrenceNoteRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.Note() - - client.get_occurrence_note(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_note_rest_bad_request(request_type=grafeas.GetNoteRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/notes/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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.get_note(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.GetNoteRequest, - dict, -]) -def test_get_note_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/notes/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 = grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.get_note(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == 'name_value' - assert response.short_description == 'short_description_value' - assert response.long_description == 'long_description_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ['related_note_names_value'] - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_note_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "post_get_note") as post, \ - mock.patch.object(transports.GrafeasRestInterceptor, "pre_get_note") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.GetNoteRequest.pb(grafeas.GetNoteRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = grafeas.Note.to_json(grafeas.Note()) - req.return_value.content = return_value - - request = grafeas.GetNoteRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.Note() - - client.get_note(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_notes_rest_bad_request(request_type=grafeas.ListNotesRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'parent': 'projects/sample1'} - 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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.list_notes(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.ListNotesRequest, - dict, -]) -def test_list_notes_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'parent': 'projects/sample1'} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), 'request') as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.ListNotesResponse( - next_page_token='next_page_token_value', - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.ListNotesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.list_notes(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListNotesPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_notes_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "post_list_notes") as post, \ - mock.patch.object(transports.GrafeasRestInterceptor, "pre_list_notes") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.ListNotesRequest.pb(grafeas.ListNotesRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = grafeas.ListNotesResponse.to_json(grafeas.ListNotesResponse()) - req.return_value.content = return_value - - request = grafeas.ListNotesRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.ListNotesResponse() - - client.list_notes(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - - -def test_delete_note_rest_bad_request(request_type=grafeas.DeleteNoteRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/notes/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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.delete_note(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.DeleteNoteRequest, - dict, -]) -def test_delete_note_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/notes/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 = None - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - 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_note(request) - - # Establish that the response is the type that we expect. - assert response is None - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_note_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "pre_delete_note") as pre: - pre.assert_not_called() - pb_message = grafeas.DeleteNoteRequest.pb(grafeas.DeleteNoteRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - - request = grafeas.DeleteNoteRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - - client.delete_note(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - - -def test_create_note_rest_bad_request(request_type=grafeas.CreateNoteRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'parent': 'projects/sample1'} - 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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.create_note(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.CreateNoteRequest, - dict, -]) -def test_create_note_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'parent': 'projects/sample1'} - request_init["note"] = {'name': 'name_value', 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'kind': 1, 'related_url': [{'url': 'url_value', 'label': 'label_value'}], 'expiration_time': {'seconds': 751, 'nanos': 543}, 'create_time': {}, 'update_time': {}, 'related_note_names': ['related_note_names_value1', 'related_note_names_value2'], 'vulnerability': {'cvss_score': 0.1082, 'severity': 1, 'details': [{'severity_name': 'severity_name_value', 'description': 'description_value', 'package_type': 'package_type_value', 'affected_cpe_uri': 'affected_cpe_uri_value', 'affected_package': 'affected_package_value', 'affected_version_start': {'epoch': 527, 'name': 'name_value', 'revision': 'revision_value', 'inclusive': True, 'kind': 1, 'full_name': 'full_name_value'}, 'affected_version_end': {}, 'fixed_cpe_uri': 'fixed_cpe_uri_value', 'fixed_package': 'fixed_package_value', 'fixed_version': {}, 'is_obsolete': True, 'source_update_time': {}, 'source': 'source_value', 'vendor': 'vendor_value'}], 'cvss_v3': {'base_score': 0.1046, 'exploitability_score': 0.21580000000000002, 'impact_score': 0.1273, 'attack_vector': 1, 'attack_complexity': 1, 'privileges_required': 1, 'user_interaction': 1, 'scope': 1, 'confidentiality_impact': 1, 'integrity_impact': 1, 'availability_impact': 1}, 'windows_details': [{'cpe_uri': 'cpe_uri_value', 'name': 'name_value', 'description': 'description_value', 'fixing_kbs': [{'name': 'name_value', 'url': 'url_value'}]}], 'source_update_time': {}, 'cvss_version': 1, 'cvss_v2': {'base_score': 0.1046, 'exploitability_score': 0.21580000000000002, 'impact_score': 0.1273, 'attack_vector': 1, 'attack_complexity': 1, 'authentication': 1, 'privileges_required': 1, 'user_interaction': 1, 'scope': 1, 'confidentiality_impact': 1, 'integrity_impact': 1, 'availability_impact': 1}}, 'build': {'builder_version': 'builder_version_value'}, 'image': {'resource_url': 'resource_url_value', 'fingerprint': {'v1_name': 'v1_name_value', 'v2_blob': ['v2_blob_value1', 'v2_blob_value2'], 'v2_name': 'v2_name_value'}}, 'package': {'name': 'name_value', 'distribution': [{'cpe_uri': 'cpe_uri_value', 'architecture': 1, 'latest_version': {}, 'maintainer': 'maintainer_value', 'url': 'url_value', 'description': 'description_value'}], 'package_type': 'package_type_value', 'cpe_uri': 'cpe_uri_value', 'architecture': 1, 'version': {}, 'maintainer': 'maintainer_value', 'url': 'url_value', 'description': 'description_value', 'license_': {'expression': 'expression_value', 'comments': 'comments_value'}, 'digest': [{'algo': 'algo_value', 'digest_bytes': b'digest_bytes_blob'}]}, 'deployment': {'resource_uri': ['resource_uri_value1', 'resource_uri_value2']}, 'discovery': {'analysis_kind': 1}, 'attestation': {'hint': {'human_readable_name': 'human_readable_name_value'}}, 'upgrade': {'package': 'package_value', 'version': {}, 'distributions': [{'cpe_uri': 'cpe_uri_value', 'classification': 'classification_value', 'severity': 'severity_value', 'cve': ['cve_value1', 'cve_value2']}], 'windows_update': {'identity': {'update_id': 'update_id_value', 'revision': 879}, 'title': 'title_value', 'description': 'description_value', 'categories': [{'category_id': 'category_id_value', 'name': 'name_value'}], 'kb_article_ids': ['kb_article_ids_value1', 'kb_article_ids_value2'], 'support_url': 'support_url_value', 'last_published_timestamp': {}}}, 'compliance': {'title': 'title_value', 'description': 'description_value', 'version': [{'cpe_uri': 'cpe_uri_value', 'benchmark_document': 'benchmark_document_value', 'version': 'version_value'}], 'rationale': 'rationale_value', 'remediation': 'remediation_value', 'cis_benchmark': {'profile_level': 1384, 'severity': 1}, 'scan_instructions': b'scan_instructions_blob', 'impact': 'impact_value'}, 'dsse_attestation': {'hint': {'human_readable_name': 'human_readable_name_value'}}, 'vulnerability_assessment': {'title': 'title_value', 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'language_code': 'language_code_value', 'publisher': {'name': 'name_value', 'issuing_authority': 'issuing_authority_value', 'publisher_namespace': 'publisher_namespace_value'}, 'product': {'name': 'name_value', 'id': 'id_value', 'generic_uri': 'generic_uri_value'}, 'assessment': {'cve': 'cve_value', 'vulnerability_id': 'vulnerability_id_value', 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'related_uris': {}, 'state': 1, 'impacts': ['impacts_value1', 'impacts_value2'], 'justification': {'justification_type': 1, 'details': 'details_value'}, 'remediations': [{'remediation_type': 1, 'details': 'details_value', 'remediation_uri': {}}]}}, 'sbom_reference': {'format_': 'format__value', 'version': 'version_value'}} - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = grafeas.CreateNoteRequest.meta.fields["note"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["note"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - {"field": field, "subfield": subfield, "is_repeated": is_repeated} - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["note"][field])): - del request_init["note"][field][i][subfield] - else: - del request_init["note"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), 'request') as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.create_note(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == 'name_value' - assert response.short_description == 'short_description_value' - assert response.long_description == 'long_description_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ['related_note_names_value'] - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_note_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "post_create_note") as post, \ - mock.patch.object(transports.GrafeasRestInterceptor, "pre_create_note") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.CreateNoteRequest.pb(grafeas.CreateNoteRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = grafeas.Note.to_json(grafeas.Note()) - req.return_value.content = return_value - - request = grafeas.CreateNoteRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.Note() - - client.create_note(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - - -def test_batch_create_notes_rest_bad_request(request_type=grafeas.BatchCreateNotesRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'parent': 'projects/sample1'} - 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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.batch_create_notes(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.BatchCreateNotesRequest, - dict, -]) -def test_batch_create_notes_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'parent': 'projects/sample1'} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), 'request') as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.BatchCreateNotesResponse( - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.BatchCreateNotesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.batch_create_notes(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.BatchCreateNotesResponse) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_batch_create_notes_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "post_batch_create_notes") as post, \ - mock.patch.object(transports.GrafeasRestInterceptor, "pre_batch_create_notes") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.BatchCreateNotesRequest.pb(grafeas.BatchCreateNotesRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = grafeas.BatchCreateNotesResponse.to_json(grafeas.BatchCreateNotesResponse()) - req.return_value.content = return_value - - request = grafeas.BatchCreateNotesRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.BatchCreateNotesResponse() - - client.batch_create_notes(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_note_rest_bad_request(request_type=grafeas.UpdateNoteRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/notes/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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.update_note(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.UpdateNoteRequest, - dict, -]) -def test_update_note_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/notes/sample2'} - request_init["note"] = {'name': 'name_value', 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'kind': 1, 'related_url': [{'url': 'url_value', 'label': 'label_value'}], 'expiration_time': {'seconds': 751, 'nanos': 543}, 'create_time': {}, 'update_time': {}, 'related_note_names': ['related_note_names_value1', 'related_note_names_value2'], 'vulnerability': {'cvss_score': 0.1082, 'severity': 1, 'details': [{'severity_name': 'severity_name_value', 'description': 'description_value', 'package_type': 'package_type_value', 'affected_cpe_uri': 'affected_cpe_uri_value', 'affected_package': 'affected_package_value', 'affected_version_start': {'epoch': 527, 'name': 'name_value', 'revision': 'revision_value', 'inclusive': True, 'kind': 1, 'full_name': 'full_name_value'}, 'affected_version_end': {}, 'fixed_cpe_uri': 'fixed_cpe_uri_value', 'fixed_package': 'fixed_package_value', 'fixed_version': {}, 'is_obsolete': True, 'source_update_time': {}, 'source': 'source_value', 'vendor': 'vendor_value'}], 'cvss_v3': {'base_score': 0.1046, 'exploitability_score': 0.21580000000000002, 'impact_score': 0.1273, 'attack_vector': 1, 'attack_complexity': 1, 'privileges_required': 1, 'user_interaction': 1, 'scope': 1, 'confidentiality_impact': 1, 'integrity_impact': 1, 'availability_impact': 1}, 'windows_details': [{'cpe_uri': 'cpe_uri_value', 'name': 'name_value', 'description': 'description_value', 'fixing_kbs': [{'name': 'name_value', 'url': 'url_value'}]}], 'source_update_time': {}, 'cvss_version': 1, 'cvss_v2': {'base_score': 0.1046, 'exploitability_score': 0.21580000000000002, 'impact_score': 0.1273, 'attack_vector': 1, 'attack_complexity': 1, 'authentication': 1, 'privileges_required': 1, 'user_interaction': 1, 'scope': 1, 'confidentiality_impact': 1, 'integrity_impact': 1, 'availability_impact': 1}}, 'build': {'builder_version': 'builder_version_value'}, 'image': {'resource_url': 'resource_url_value', 'fingerprint': {'v1_name': 'v1_name_value', 'v2_blob': ['v2_blob_value1', 'v2_blob_value2'], 'v2_name': 'v2_name_value'}}, 'package': {'name': 'name_value', 'distribution': [{'cpe_uri': 'cpe_uri_value', 'architecture': 1, 'latest_version': {}, 'maintainer': 'maintainer_value', 'url': 'url_value', 'description': 'description_value'}], 'package_type': 'package_type_value', 'cpe_uri': 'cpe_uri_value', 'architecture': 1, 'version': {}, 'maintainer': 'maintainer_value', 'url': 'url_value', 'description': 'description_value', 'license_': {'expression': 'expression_value', 'comments': 'comments_value'}, 'digest': [{'algo': 'algo_value', 'digest_bytes': b'digest_bytes_blob'}]}, 'deployment': {'resource_uri': ['resource_uri_value1', 'resource_uri_value2']}, 'discovery': {'analysis_kind': 1}, 'attestation': {'hint': {'human_readable_name': 'human_readable_name_value'}}, 'upgrade': {'package': 'package_value', 'version': {}, 'distributions': [{'cpe_uri': 'cpe_uri_value', 'classification': 'classification_value', 'severity': 'severity_value', 'cve': ['cve_value1', 'cve_value2']}], 'windows_update': {'identity': {'update_id': 'update_id_value', 'revision': 879}, 'title': 'title_value', 'description': 'description_value', 'categories': [{'category_id': 'category_id_value', 'name': 'name_value'}], 'kb_article_ids': ['kb_article_ids_value1', 'kb_article_ids_value2'], 'support_url': 'support_url_value', 'last_published_timestamp': {}}}, 'compliance': {'title': 'title_value', 'description': 'description_value', 'version': [{'cpe_uri': 'cpe_uri_value', 'benchmark_document': 'benchmark_document_value', 'version': 'version_value'}], 'rationale': 'rationale_value', 'remediation': 'remediation_value', 'cis_benchmark': {'profile_level': 1384, 'severity': 1}, 'scan_instructions': b'scan_instructions_blob', 'impact': 'impact_value'}, 'dsse_attestation': {'hint': {'human_readable_name': 'human_readable_name_value'}}, 'vulnerability_assessment': {'title': 'title_value', 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'language_code': 'language_code_value', 'publisher': {'name': 'name_value', 'issuing_authority': 'issuing_authority_value', 'publisher_namespace': 'publisher_namespace_value'}, 'product': {'name': 'name_value', 'id': 'id_value', 'generic_uri': 'generic_uri_value'}, 'assessment': {'cve': 'cve_value', 'vulnerability_id': 'vulnerability_id_value', 'short_description': 'short_description_value', 'long_description': 'long_description_value', 'related_uris': {}, 'state': 1, 'impacts': ['impacts_value1', 'impacts_value2'], 'justification': {'justification_type': 1, 'details': 'details_value'}, 'remediations': [{'remediation_type': 1, 'details': 'details_value', 'remediation_uri': {}}]}}, 'sbom_reference': {'format_': 'format__value', 'version': 'version_value'}} - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = grafeas.UpdateNoteRequest.meta.fields["note"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["note"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - {"field": field, "subfield": subfield, "is_repeated": is_repeated} - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["note"][field])): - del request_init["note"][field][i][subfield] - else: - del request_init["note"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), 'request') as req: - # Designate an appropriate value for the returned response. - return_value = grafeas.Note( - name='name_value', - short_description='short_description_value', - long_description='long_description_value', - kind=common.NoteKind.VULNERABILITY, - related_note_names=['related_note_names_value'], - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.Note.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.update_note(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, grafeas.Note) - assert response.name == 'name_value' - assert response.short_description == 'short_description_value' - assert response.long_description == 'long_description_value' - assert response.kind == common.NoteKind.VULNERABILITY - assert response.related_note_names == ['related_note_names_value'] - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_note_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "post_update_note") as post, \ - mock.patch.object(transports.GrafeasRestInterceptor, "pre_update_note") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.UpdateNoteRequest.pb(grafeas.UpdateNoteRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = grafeas.Note.to_json(grafeas.Note()) - req.return_value.content = return_value - - request = grafeas.UpdateNoteRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.Note() - - client.update_note(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_note_occurrences_rest_bad_request(request_type=grafeas.ListNoteOccurrencesRequest): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/notes/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 = mock.Mock() - json_return_value = '' - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - client.list_note_occurrences(request) - - -@pytest.mark.parametrize("request_type", [ - grafeas.ListNoteOccurrencesRequest, - dict, -]) -def test_list_note_occurrences_rest_call_success(request_type): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {'name': 'projects/sample1/notes/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 = grafeas.ListNoteOccurrencesResponse( - next_page_token='next_page_token_value', - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = grafeas.ListNoteOccurrencesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode('UTF-8') - req.return_value = response_value - response = client.list_note_occurrences(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListNoteOccurrencesPager) - assert response.next_page_token == 'next_page_token_value' - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_note_occurrences_rest_interceptors(null_interceptor): - transport = transports.GrafeasRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.GrafeasRestInterceptor(), - ) - client = GrafeasClient(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.GrafeasRestInterceptor, "post_list_note_occurrences") as post, \ - mock.patch.object(transports.GrafeasRestInterceptor, "pre_list_note_occurrences") as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = grafeas.ListNoteOccurrencesRequest.pb(grafeas.ListNoteOccurrencesRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - return_value = grafeas.ListNoteOccurrencesResponse.to_json(grafeas.ListNoteOccurrencesResponse()) - req.return_value.content = return_value - - request = grafeas.ListNoteOccurrencesRequest() - metadata =[ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = grafeas.ListNoteOccurrencesResponse() - - client.list_note_occurrences(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) - - pre.assert_called_once() - post.assert_called_once() - -def test_initialize_client_w_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_occurrence_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence), - '__call__') as call: - client.get_occurrence(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.GetOccurrenceRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_occurrences_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_occurrences), - '__call__') as call: - client.list_occurrences(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.ListOccurrencesRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_occurrence_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_occurrence), - '__call__') as call: - client.delete_occurrence(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.DeleteOccurrenceRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_occurrence_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_occurrence), - '__call__') as call: - client.create_occurrence(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.CreateOccurrenceRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_batch_create_occurrences_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_occurrences), - '__call__') as call: - client.batch_create_occurrences(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.BatchCreateOccurrencesRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_occurrence_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_occurrence), - '__call__') as call: - client.update_occurrence(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.UpdateOccurrenceRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_occurrence_note_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_occurrence_note), - '__call__') as call: - client.get_occurrence_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.GetOccurrenceNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_note_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.get_note), - '__call__') as call: - client.get_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.GetNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_notes_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_notes), - '__call__') as call: - client.list_notes(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.ListNotesRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_note_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.delete_note), - '__call__') as call: - client.delete_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.DeleteNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_create_note_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.create_note), - '__call__') as call: - client.create_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.CreateNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_batch_create_notes_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.batch_create_notes), - '__call__') as call: - client.batch_create_notes(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.BatchCreateNotesRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_note_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.update_note), - '__call__') as call: - client.update_note(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.UpdateNoteRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_note_occurrences_empty_call_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_note_occurrences), - '__call__') as call: - client.list_note_occurrences(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = grafeas.ListNoteOccurrencesRequest() - - assert args[0] == request_msg - - -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert isinstance( - client.transport, - transports.GrafeasGrpcTransport, - ) - -def test_grafeas_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.GrafeasTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json" - ) - - -def test_grafeas_base_transport(): - # Instantiate the base transport. - with mock.patch('grafeas.grafeas_v1.services.grafeas.transports.GrafeasTransport.__init__') as Transport: - Transport.return_value = None - transport = transports.GrafeasTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - 'get_occurrence', - 'list_occurrences', - 'delete_occurrence', - 'create_occurrence', - 'batch_create_occurrences', - 'update_occurrence', - 'get_occurrence_note', - 'get_note', - 'list_notes', - 'delete_note', - 'create_note', - 'batch_create_notes', - 'update_note', - 'list_note_occurrences', - ) - 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_grafeas_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('grafeas.grafeas_v1.services.grafeas.transports.GrafeasTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.GrafeasTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with("credentials.json", - scopes=None, - default_scopes=( -), - quota_project_id="octopus", - ) - - -def test_grafeas_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('grafeas.grafeas_v1.services.grafeas.transports.GrafeasTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.GrafeasTransport() - adc.assert_called_once() - - -def test_grafeas_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) - GrafeasClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=( -), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.GrafeasGrpcTransport, - transports.GrafeasGrpcAsyncIOTransport, - ], -) -def test_grafeas_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=(), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.GrafeasGrpcTransport, - transports.GrafeasGrpcAsyncIOTransport, - transports.GrafeasRestTransport, - ], -) -def test_grafeas_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.GrafeasGrpcTransport, grpc_helpers), - (transports.GrafeasGrpcAsyncIOTransport, grpc_helpers_async) - ], -) -def test_grafeas_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( - "containeranalysis.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=( -), - scopes=["1", "2"], - default_host="containeranalysis.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("transport_class", [transports.GrafeasGrpcTransport, transports.GrafeasGrpcAsyncIOTransport]) -def test_grafeas_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_grafeas_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.GrafeasRestTransport ( - 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_grafeas_host_no_port(transport_name): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='containeranalysis.googleapis.com'), - transport=transport_name, - ) - assert client.transport._host == ( - 'containeranalysis.googleapis.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else 'https://containeranalysis.googleapis.com' - ) - -@pytest.mark.parametrize("transport_name", [ - "grpc", - "grpc_asyncio", - "rest", -]) -def test_grafeas_host_with_port(transport_name): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='containeranalysis.googleapis.com:8000'), - transport=transport_name, - ) - assert client.transport._host == ( - 'containeranalysis.googleapis.com:8000' - if transport_name in ['grpc', 'grpc_asyncio'] - else 'https://containeranalysis.googleapis.com:8000' - ) - -@pytest.mark.parametrize("transport_name", [ - "rest", -]) -def test_grafeas_client_transport_session_collision(transport_name): - creds1 = ga_credentials.AnonymousCredentials() - creds2 = ga_credentials.AnonymousCredentials() - client1 = GrafeasClient( - credentials=creds1, - transport=transport_name, - ) - client2 = GrafeasClient( - credentials=creds2, - transport=transport_name, - ) - session1 = client1.transport.get_occurrence._session - session2 = client2.transport.get_occurrence._session - assert session1 != session2 - session1 = client1.transport.list_occurrences._session - session2 = client2.transport.list_occurrences._session - assert session1 != session2 - session1 = client1.transport.delete_occurrence._session - session2 = client2.transport.delete_occurrence._session - assert session1 != session2 - session1 = client1.transport.create_occurrence._session - session2 = client2.transport.create_occurrence._session - assert session1 != session2 - session1 = client1.transport.batch_create_occurrences._session - session2 = client2.transport.batch_create_occurrences._session - assert session1 != session2 - session1 = client1.transport.update_occurrence._session - session2 = client2.transport.update_occurrence._session - assert session1 != session2 - session1 = client1.transport.get_occurrence_note._session - session2 = client2.transport.get_occurrence_note._session - assert session1 != session2 - session1 = client1.transport.get_note._session - session2 = client2.transport.get_note._session - assert session1 != session2 - session1 = client1.transport.list_notes._session - session2 = client2.transport.list_notes._session - assert session1 != session2 - session1 = client1.transport.delete_note._session - session2 = client2.transport.delete_note._session - assert session1 != session2 - session1 = client1.transport.create_note._session - session2 = client2.transport.create_note._session - assert session1 != session2 - session1 = client1.transport.batch_create_notes._session - session2 = client2.transport.batch_create_notes._session - assert session1 != session2 - session1 = client1.transport.update_note._session - session2 = client2.transport.update_note._session - assert session1 != session2 - session1 = client1.transport.list_note_occurrences._session - session2 = client2.transport.list_note_occurrences._session - assert session1 != session2 -def test_grafeas_grpc_transport_channel(): - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.GrafeasGrpcTransport( - 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_grafeas_grpc_asyncio_transport_channel(): - channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.GrafeasGrpcAsyncIOTransport( - 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.GrafeasGrpcTransport, transports.GrafeasGrpcAsyncIOTransport]) -def test_grafeas_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.GrafeasGrpcTransport, transports.GrafeasGrpcAsyncIOTransport]) -def test_grafeas_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_note_path(): - project = "squid" - note = "clam" - expected = "projects/{project}/notes/{note}".format(project=project, note=note, ) - actual = GrafeasClient.note_path(project, note) - assert expected == actual - - -def test_parse_note_path(): - expected = { - "project": "whelk", - "note": "octopus", - } - path = GrafeasClient.note_path(**expected) - - # Check that the path construction is reversible. - actual = GrafeasClient.parse_note_path(path) - assert expected == actual - -def test_occurrence_path(): - project = "oyster" - occurrence = "nudibranch" - expected = "projects/{project}/occurrences/{occurrence}".format(project=project, occurrence=occurrence, ) - actual = GrafeasClient.occurrence_path(project, occurrence) - assert expected == actual - - -def test_parse_occurrence_path(): - expected = { - "project": "cuttlefish", - "occurrence": "mussel", - } - path = GrafeasClient.occurrence_path(**expected) - - # Check that the path construction is reversible. - actual = GrafeasClient.parse_occurrence_path(path) - assert expected == actual - -def test_project_path(): - project = "winkle" - expected = "projects/{project}".format(project=project, ) - actual = GrafeasClient.project_path(project) - assert expected == actual - - -def test_parse_project_path(): - expected = { - "project": "nautilus", - } - path = GrafeasClient.project_path(**expected) - - # Check that the path construction is reversible. - actual = GrafeasClient.parse_project_path(path) - assert expected == actual - -def test_common_billing_account_path(): - billing_account = "scallop" - expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - actual = GrafeasClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "abalone", - } - path = GrafeasClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = GrafeasClient.parse_common_billing_account_path(path) - assert expected == actual - -def test_common_folder_path(): - folder = "squid" - expected = "folders/{folder}".format(folder=folder, ) - actual = GrafeasClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "clam", - } - path = GrafeasClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = GrafeasClient.parse_common_folder_path(path) - assert expected == actual - -def test_common_organization_path(): - organization = "whelk" - expected = "organizations/{organization}".format(organization=organization, ) - actual = GrafeasClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "octopus", - } - path = GrafeasClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = GrafeasClient.parse_common_organization_path(path) - assert expected == actual - -def test_common_project_path(): - project = "oyster" - expected = "projects/{project}".format(project=project, ) - actual = GrafeasClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "nudibranch", - } - path = GrafeasClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = GrafeasClient.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 = GrafeasClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "winkle", - "location": "nautilus", - } - path = GrafeasClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = GrafeasClient.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.GrafeasTransport, '_prep_wrapped_messages') as prep: - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object(transports.GrafeasTransport, '_prep_wrapped_messages') as prep: - transport_class = GrafeasClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -def test_transport_close_grpc(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc" - ) - with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -@pytest.mark.asyncio -async def test_transport_close_grpc_asyncio(): - client = GrafeasAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio" - ) - with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: - async with client: - close.assert_not_called() - close.assert_called_once() - - -def test_transport_close_rest(): - client = GrafeasClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - with mock.patch.object(type(getattr(client.transport, "_session")), "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 = GrafeasClient( - 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", [ - (GrafeasClient, transports.GrafeasGrpcTransport), - (GrafeasAsyncClient, transports.GrafeasGrpcAsyncIOTransport), -]) -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_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_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/packages/google-shopping-merchant-promotions/.flake8 b/packages/google-shopping-merchant-promotions/.flake8 index 87f6e408c47d..32986c79287a 100644 --- a/packages/google-shopping-merchant-promotions/.flake8 +++ b/packages/google-shopping-merchant-promotions/.flake8 @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-merchant-promotions/CONTRIBUTING.rst b/packages/google-shopping-merchant-promotions/CONTRIBUTING.rst index db38f3e5c288..b6f0f69ca254 100644 --- a/packages/google-shopping-merchant-promotions/CONTRIBUTING.rst +++ b/packages/google-shopping-merchant-promotions/CONTRIBUTING.rst @@ -22,7 +22,7 @@ In order to add a feature: documentation. - The feature must work fully on the following CPython versions: - 3.7, 3.8, 3.9, 3.10, 3.11 and 3.12 on both UNIX and Windows. + 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13 on both UNIX and Windows. - The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should @@ -72,7 +72,7 @@ We use `nox `__ to instrument our tests. - To run a single unit test:: - $ nox -s unit-3.12 -- -k + $ nox -s unit-3.13 -- -k .. note:: @@ -143,12 +143,12 @@ Running System Tests $ nox -s system # Run a single system test - $ nox -s system-3.12 -- -k + $ nox -s system-3.13 -- -k .. note:: - System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11 and 3.12. + System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13. For expediency, we do not run them in older versions of Python 3. This alone will not run the tests. You'll need to change some local @@ -227,6 +227,7 @@ We support: - `Python 3.10`_ - `Python 3.11`_ - `Python 3.12`_ +- `Python 3.13`_ .. _Python 3.7: https://docs.python.org/3.7/ .. _Python 3.8: https://docs.python.org/3.8/ @@ -234,6 +235,7 @@ We support: .. _Python 3.10: https://docs.python.org/3.10/ .. _Python 3.11: https://docs.python.org/3.11/ .. _Python 3.12: https://docs.python.org/3.12/ +.. _Python 3.13: https://docs.python.org/3.13/ Supported versions can be found in our ``noxfile.py`` `config`_. diff --git a/packages/google-shopping-merchant-promotions/MANIFEST.in b/packages/google-shopping-merchant-promotions/MANIFEST.in index e0a66705318e..d6814cd60037 100644 --- a/packages/google-shopping-merchant-promotions/MANIFEST.in +++ b/packages/google-shopping-merchant-promotions/MANIFEST.in @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-merchant-promotions/docs/conf.py b/packages/google-shopping-merchant-promotions/docs/conf.py index 507599599eaa..55311fad66a3 100644 --- a/packages/google-shopping-merchant-promotions/docs/conf.py +++ b/packages/google-shopping-merchant-promotions/docs/conf.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py index 9d91e27b1130..efd1401a514c 100644 --- a/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py +++ b/packages/google-shopping-merchant-promotions/google/shopping/merchant_promotions_v1beta/services/promotions_service/transports/rest.py @@ -41,7 +41,7 @@ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, - rest_version=requests_version, + rest_version=f"requests@{requests_version}", ) diff --git a/packages/google-shopping-merchant-promotions/noxfile.py b/packages/google-shopping-merchant-promotions/noxfile.py index 67b7265f7586..a9ceef47133c 100644 --- a/packages/google-shopping-merchant-promotions/noxfile.py +++ b/packages/google-shopping-merchant-promotions/noxfile.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -35,7 +35,15 @@ DEFAULT_PYTHON_VERSION = "3.10" -UNIT_TEST_PYTHON_VERSIONS: List[str] = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] +UNIT_TEST_PYTHON_VERSIONS: List[str] = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", +] UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", "asyncmock", @@ -49,7 +57,7 @@ UNIT_TEST_EXTRAS: List[str] = [] UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} -SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12"] +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] SYSTEM_TEST_STANDARD_DEPENDENCIES = [ "mock", "pytest", @@ -168,7 +176,7 @@ def install_unittest_dependencies(session, *constraints): def unit(session, protobuf_implementation): # Install all test dependencies, then install this package in-place. - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"): + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): session.skip("cpp implementation is not supported in python 3.11+") constraints_path = str( @@ -368,7 +376,7 @@ def docfx(session): ) -@nox.session(python="3.12") +@nox.session(python="3.13") @nox.parametrize( "protobuf_implementation", ["python", "upb", "cpp"], @@ -376,7 +384,7 @@ def docfx(session): def prerelease_deps(session, protobuf_implementation): """Run all tests with prerelease versions of dependencies installed.""" - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"): + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): session.skip("cpp implementation is not supported in python 3.11+") # Install all dependencies diff --git a/packages/google-shopping-merchant-promotions/scripts/decrypt-secrets.sh b/packages/google-shopping-merchant-promotions/scripts/decrypt-secrets.sh index 0018b421ddf8..120b0ddc4364 100755 --- a/packages/google-shopping-merchant-promotions/scripts/decrypt-secrets.sh +++ b/packages/google-shopping-merchant-promotions/scripts/decrypt-secrets.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2023 Google LLC All rights reserved. +# Copyright 2024 Google LLC All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-merchant-promotions/setup.py b/packages/google-shopping-merchant-promotions/setup.py index ef159a1bd624..5229fba2efec 100644 --- a/packages/google-shopping-merchant-promotions/setup.py +++ b/packages/google-shopping-merchant-promotions/setup.py @@ -46,6 +46,7 @@ # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", "proto-plus >= 1.22.3, <2.0.0dev", + "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-shopping-type >= 0.1.6, <1.0.0dev", ] @@ -85,6 +86,7 @@ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "Topic :: Internet", ], diff --git a/owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.13.txt b/packages/google-shopping-merchant-promotions/testing/constraints-3.13.txt similarity index 100% rename from owl-bot-staging/google-shopping-merchant-promotions/v1beta/testing/constraints-3.13.txt rename to packages/google-shopping-merchant-promotions/testing/constraints-3.13.txt diff --git a/packages/google-shopping-merchant-quota/.flake8 b/packages/google-shopping-merchant-quota/.flake8 index 87f6e408c47d..32986c79287a 100644 --- a/packages/google-shopping-merchant-quota/.flake8 +++ b/packages/google-shopping-merchant-quota/.flake8 @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-merchant-quota/CONTRIBUTING.rst b/packages/google-shopping-merchant-quota/CONTRIBUTING.rst index cfb95d38abb4..6ed2db1933e3 100644 --- a/packages/google-shopping-merchant-quota/CONTRIBUTING.rst +++ b/packages/google-shopping-merchant-quota/CONTRIBUTING.rst @@ -22,7 +22,7 @@ In order to add a feature: documentation. - The feature must work fully on the following CPython versions: - 3.7, 3.8, 3.9, 3.10, 3.11 and 3.12 on both UNIX and Windows. + 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13 on both UNIX and Windows. - The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should @@ -72,7 +72,7 @@ We use `nox `__ to instrument our tests. - To run a single unit test:: - $ nox -s unit-3.12 -- -k + $ nox -s unit-3.13 -- -k .. note:: @@ -143,12 +143,12 @@ Running System Tests $ nox -s system # Run a single system test - $ nox -s system-3.12 -- -k + $ nox -s system-3.13 -- -k .. note:: - System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11 and 3.12. + System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13. For expediency, we do not run them in older versions of Python 3. This alone will not run the tests. You'll need to change some local @@ -227,6 +227,7 @@ We support: - `Python 3.10`_ - `Python 3.11`_ - `Python 3.12`_ +- `Python 3.13`_ .. _Python 3.7: https://docs.python.org/3.7/ .. _Python 3.8: https://docs.python.org/3.8/ @@ -234,6 +235,7 @@ We support: .. _Python 3.10: https://docs.python.org/3.10/ .. _Python 3.11: https://docs.python.org/3.11/ .. _Python 3.12: https://docs.python.org/3.12/ +.. _Python 3.13: https://docs.python.org/3.13/ Supported versions can be found in our ``noxfile.py`` `config`_. diff --git a/packages/google-shopping-merchant-quota/MANIFEST.in b/packages/google-shopping-merchant-quota/MANIFEST.in index e0a66705318e..d6814cd60037 100644 --- a/packages/google-shopping-merchant-quota/MANIFEST.in +++ b/packages/google-shopping-merchant-quota/MANIFEST.in @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-merchant-quota/docs/conf.py b/packages/google-shopping-merchant-quota/docs/conf.py index 35b5133f88c5..e5b5da7a2381 100644 --- a/packages/google-shopping-merchant-quota/docs/conf.py +++ b/packages/google-shopping-merchant-quota/docs/conf.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py index f2f450459f06..b4b942f6e478 100644 --- a/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py +++ b/packages/google-shopping-merchant-quota/google/shopping/merchant_quota_v1beta/services/quota_service/transports/rest.py @@ -41,7 +41,7 @@ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, - rest_version=requests_version, + rest_version=f"requests@{requests_version}", ) diff --git a/packages/google-shopping-merchant-quota/noxfile.py b/packages/google-shopping-merchant-quota/noxfile.py index 67b7265f7586..a9ceef47133c 100644 --- a/packages/google-shopping-merchant-quota/noxfile.py +++ b/packages/google-shopping-merchant-quota/noxfile.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -35,7 +35,15 @@ DEFAULT_PYTHON_VERSION = "3.10" -UNIT_TEST_PYTHON_VERSIONS: List[str] = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] +UNIT_TEST_PYTHON_VERSIONS: List[str] = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", +] UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", "asyncmock", @@ -49,7 +57,7 @@ UNIT_TEST_EXTRAS: List[str] = [] UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} -SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12"] +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] SYSTEM_TEST_STANDARD_DEPENDENCIES = [ "mock", "pytest", @@ -168,7 +176,7 @@ def install_unittest_dependencies(session, *constraints): def unit(session, protobuf_implementation): # Install all test dependencies, then install this package in-place. - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"): + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): session.skip("cpp implementation is not supported in python 3.11+") constraints_path = str( @@ -368,7 +376,7 @@ def docfx(session): ) -@nox.session(python="3.12") +@nox.session(python="3.13") @nox.parametrize( "protobuf_implementation", ["python", "upb", "cpp"], @@ -376,7 +384,7 @@ def docfx(session): def prerelease_deps(session, protobuf_implementation): """Run all tests with prerelease versions of dependencies installed.""" - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"): + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): session.skip("cpp implementation is not supported in python 3.11+") # Install all dependencies diff --git a/packages/google-shopping-merchant-quota/scripts/decrypt-secrets.sh b/packages/google-shopping-merchant-quota/scripts/decrypt-secrets.sh index 0018b421ddf8..120b0ddc4364 100755 --- a/packages/google-shopping-merchant-quota/scripts/decrypt-secrets.sh +++ b/packages/google-shopping-merchant-quota/scripts/decrypt-secrets.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2023 Google LLC All rights reserved. +# Copyright 2024 Google LLC All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-merchant-quota/setup.py b/packages/google-shopping-merchant-quota/setup.py index 88372d82ef49..837962199600 100644 --- a/packages/google-shopping-merchant-quota/setup.py +++ b/packages/google-shopping-merchant-quota/setup.py @@ -46,6 +46,7 @@ # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", "proto-plus >= 1.22.3, <2.0.0dev", + "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", ] extras = {} @@ -84,6 +85,7 @@ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "Topic :: Internet", ], diff --git a/owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.13.txt b/packages/google-shopping-merchant-quota/testing/constraints-3.13.txt similarity index 100% rename from owl-bot-staging/google-shopping-merchant-quota/v1beta/testing/constraints-3.13.txt rename to packages/google-shopping-merchant-quota/testing/constraints-3.13.txt diff --git a/packages/google-shopping-merchant-reports/.flake8 b/packages/google-shopping-merchant-reports/.flake8 index 87f6e408c47d..32986c79287a 100644 --- a/packages/google-shopping-merchant-reports/.flake8 +++ b/packages/google-shopping-merchant-reports/.flake8 @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-merchant-reports/CONTRIBUTING.rst b/packages/google-shopping-merchant-reports/CONTRIBUTING.rst index 1c06c2e4b294..92fe9dcbe86e 100644 --- a/packages/google-shopping-merchant-reports/CONTRIBUTING.rst +++ b/packages/google-shopping-merchant-reports/CONTRIBUTING.rst @@ -22,7 +22,7 @@ In order to add a feature: documentation. - The feature must work fully on the following CPython versions: - 3.7, 3.8, 3.9, 3.10, 3.11 and 3.12 on both UNIX and Windows. + 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13 on both UNIX and Windows. - The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should @@ -72,7 +72,7 @@ We use `nox `__ to instrument our tests. - To run a single unit test:: - $ nox -s unit-3.12 -- -k + $ nox -s unit-3.13 -- -k .. note:: @@ -143,12 +143,12 @@ Running System Tests $ nox -s system # Run a single system test - $ nox -s system-3.12 -- -k + $ nox -s system-3.13 -- -k .. note:: - System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11 and 3.12. + System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13. For expediency, we do not run them in older versions of Python 3. This alone will not run the tests. You'll need to change some local @@ -227,6 +227,7 @@ We support: - `Python 3.10`_ - `Python 3.11`_ - `Python 3.12`_ +- `Python 3.13`_ .. _Python 3.7: https://docs.python.org/3.7/ .. _Python 3.8: https://docs.python.org/3.8/ @@ -234,6 +235,7 @@ We support: .. _Python 3.10: https://docs.python.org/3.10/ .. _Python 3.11: https://docs.python.org/3.11/ .. _Python 3.12: https://docs.python.org/3.12/ +.. _Python 3.13: https://docs.python.org/3.13/ Supported versions can be found in our ``noxfile.py`` `config`_. diff --git a/packages/google-shopping-merchant-reports/MANIFEST.in b/packages/google-shopping-merchant-reports/MANIFEST.in index e0a66705318e..d6814cd60037 100644 --- a/packages/google-shopping-merchant-reports/MANIFEST.in +++ b/packages/google-shopping-merchant-reports/MANIFEST.in @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-merchant-reports/docs/conf.py b/packages/google-shopping-merchant-reports/docs/conf.py index 041cac2f2f18..f2e7ec20e2e3 100644 --- a/packages/google-shopping-merchant-reports/docs/conf.py +++ b/packages/google-shopping-merchant-reports/docs/conf.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py index 421e449776e6..50a907ac8a5a 100644 --- a/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py +++ b/packages/google-shopping-merchant-reports/google/shopping/merchant_reports_v1beta/services/report_service/transports/rest.py @@ -41,7 +41,7 @@ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, - rest_version=requests_version, + rest_version=f"requests@{requests_version}", ) diff --git a/packages/google-shopping-merchant-reports/noxfile.py b/packages/google-shopping-merchant-reports/noxfile.py index 67b7265f7586..a9ceef47133c 100644 --- a/packages/google-shopping-merchant-reports/noxfile.py +++ b/packages/google-shopping-merchant-reports/noxfile.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -35,7 +35,15 @@ DEFAULT_PYTHON_VERSION = "3.10" -UNIT_TEST_PYTHON_VERSIONS: List[str] = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] +UNIT_TEST_PYTHON_VERSIONS: List[str] = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", +] UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", "asyncmock", @@ -49,7 +57,7 @@ UNIT_TEST_EXTRAS: List[str] = [] UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} -SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12"] +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] SYSTEM_TEST_STANDARD_DEPENDENCIES = [ "mock", "pytest", @@ -168,7 +176,7 @@ def install_unittest_dependencies(session, *constraints): def unit(session, protobuf_implementation): # Install all test dependencies, then install this package in-place. - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"): + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): session.skip("cpp implementation is not supported in python 3.11+") constraints_path = str( @@ -368,7 +376,7 @@ def docfx(session): ) -@nox.session(python="3.12") +@nox.session(python="3.13") @nox.parametrize( "protobuf_implementation", ["python", "upb", "cpp"], @@ -376,7 +384,7 @@ def docfx(session): def prerelease_deps(session, protobuf_implementation): """Run all tests with prerelease versions of dependencies installed.""" - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"): + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): session.skip("cpp implementation is not supported in python 3.11+") # Install all dependencies diff --git a/packages/google-shopping-merchant-reports/scripts/decrypt-secrets.sh b/packages/google-shopping-merchant-reports/scripts/decrypt-secrets.sh index 0018b421ddf8..120b0ddc4364 100755 --- a/packages/google-shopping-merchant-reports/scripts/decrypt-secrets.sh +++ b/packages/google-shopping-merchant-reports/scripts/decrypt-secrets.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2023 Google LLC All rights reserved. +# Copyright 2024 Google LLC All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-merchant-reports/setup.py b/packages/google-shopping-merchant-reports/setup.py index ae241c3f6800..79c9a4cbe33b 100644 --- a/packages/google-shopping-merchant-reports/setup.py +++ b/packages/google-shopping-merchant-reports/setup.py @@ -46,6 +46,7 @@ # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", "proto-plus >= 1.22.3, <2.0.0dev", + "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "google-shopping-type >= 0.1.6, <1.0.0dev", ] @@ -85,6 +86,7 @@ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "Topic :: Internet", ], diff --git a/owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.13.txt b/packages/google-shopping-merchant-reports/testing/constraints-3.13.txt similarity index 100% rename from owl-bot-staging/google-shopping-merchant-reports/v1beta/testing/constraints-3.13.txt rename to packages/google-shopping-merchant-reports/testing/constraints-3.13.txt diff --git a/packages/google-shopping-type/.flake8 b/packages/google-shopping-type/.flake8 index 87f6e408c47d..32986c79287a 100644 --- a/packages/google-shopping-type/.flake8 +++ b/packages/google-shopping-type/.flake8 @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-type/CONTRIBUTING.rst b/packages/google-shopping-type/CONTRIBUTING.rst index cecda033bae6..784c0b3d8b7d 100644 --- a/packages/google-shopping-type/CONTRIBUTING.rst +++ b/packages/google-shopping-type/CONTRIBUTING.rst @@ -22,7 +22,7 @@ In order to add a feature: documentation. - The feature must work fully on the following CPython versions: - 3.7, 3.8, 3.9, 3.10, 3.11 and 3.12 on both UNIX and Windows. + 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13 on both UNIX and Windows. - The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should @@ -72,7 +72,7 @@ We use `nox `__ to instrument our tests. - To run a single unit test:: - $ nox -s unit-3.12 -- -k + $ nox -s unit-3.13 -- -k .. note:: @@ -143,12 +143,12 @@ Running System Tests $ nox -s system # Run a single system test - $ nox -s system-3.12 -- -k + $ nox -s system-3.13 -- -k .. note:: - System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11 and 3.12. + System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13. For expediency, we do not run them in older versions of Python 3. This alone will not run the tests. You'll need to change some local @@ -227,6 +227,7 @@ We support: - `Python 3.10`_ - `Python 3.11`_ - `Python 3.12`_ +- `Python 3.13`_ .. _Python 3.7: https://docs.python.org/3.7/ .. _Python 3.8: https://docs.python.org/3.8/ @@ -234,6 +235,7 @@ We support: .. _Python 3.10: https://docs.python.org/3.10/ .. _Python 3.11: https://docs.python.org/3.11/ .. _Python 3.12: https://docs.python.org/3.12/ +.. _Python 3.13: https://docs.python.org/3.13/ Supported versions can be found in our ``noxfile.py`` `config`_. diff --git a/packages/google-shopping-type/MANIFEST.in b/packages/google-shopping-type/MANIFEST.in index e0a66705318e..d6814cd60037 100644 --- a/packages/google-shopping-type/MANIFEST.in +++ b/packages/google-shopping-type/MANIFEST.in @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-type/docs/conf.py b/packages/google-shopping-type/docs/conf.py index 91d659b09879..ebfc28ae41a3 100644 --- a/packages/google-shopping-type/docs/conf.py +++ b/packages/google-shopping-type/docs/conf.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-type/docs/index.rst b/packages/google-shopping-type/docs/index.rst index 7a51dc8118c3..0ae636cad7c1 100644 --- a/packages/google-shopping-type/docs/index.rst +++ b/packages/google-shopping-type/docs/index.rst @@ -7,6 +7,7 @@ API Reference .. toctree:: :maxdepth: 2 + type/services_ type/types_ diff --git a/packages/google-shopping-type/noxfile.py b/packages/google-shopping-type/noxfile.py index 67b7265f7586..a9ceef47133c 100644 --- a/packages/google-shopping-type/noxfile.py +++ b/packages/google-shopping-type/noxfile.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -35,7 +35,15 @@ DEFAULT_PYTHON_VERSION = "3.10" -UNIT_TEST_PYTHON_VERSIONS: List[str] = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] +UNIT_TEST_PYTHON_VERSIONS: List[str] = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", +] UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", "asyncmock", @@ -49,7 +57,7 @@ UNIT_TEST_EXTRAS: List[str] = [] UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} -SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12"] +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] SYSTEM_TEST_STANDARD_DEPENDENCIES = [ "mock", "pytest", @@ -168,7 +176,7 @@ def install_unittest_dependencies(session, *constraints): def unit(session, protobuf_implementation): # Install all test dependencies, then install this package in-place. - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"): + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): session.skip("cpp implementation is not supported in python 3.11+") constraints_path = str( @@ -368,7 +376,7 @@ def docfx(session): ) -@nox.session(python="3.12") +@nox.session(python="3.13") @nox.parametrize( "protobuf_implementation", ["python", "upb", "cpp"], @@ -376,7 +384,7 @@ def docfx(session): def prerelease_deps(session, protobuf_implementation): """Run all tests with prerelease versions of dependencies installed.""" - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"): + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): session.skip("cpp implementation is not supported in python 3.11+") # Install all dependencies diff --git a/packages/google-shopping-type/scripts/decrypt-secrets.sh b/packages/google-shopping-type/scripts/decrypt-secrets.sh index 0018b421ddf8..120b0ddc4364 100755 --- a/packages/google-shopping-type/scripts/decrypt-secrets.sh +++ b/packages/google-shopping-type/scripts/decrypt-secrets.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2023 Google LLC All rights reserved. +# Copyright 2024 Google LLC All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-shopping-type/setup.py b/packages/google-shopping-type/setup.py index c8c4ed59e373..0826a35cf18f 100644 --- a/packages/google-shopping-type/setup.py +++ b/packages/google-shopping-type/setup.py @@ -44,6 +44,7 @@ # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", "proto-plus >= 1.22.3, <2.0.0dev", + "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", ] extras = {} @@ -82,6 +83,7 @@ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "Topic :: Internet", ], diff --git a/owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.13.txt b/packages/google-shopping-type/testing/constraints-3.13.txt similarity index 100% rename from owl-bot-staging/google-shopping-type/google-shopping-type-py/testing/constraints-3.13.txt rename to packages/google-shopping-type/testing/constraints-3.13.txt diff --git a/packages/grafeas/.flake8 b/packages/grafeas/.flake8 index 87f6e408c47d..32986c79287a 100644 --- a/packages/grafeas/.flake8 +++ b/packages/grafeas/.flake8 @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/grafeas/CONTRIBUTING.rst b/packages/grafeas/CONTRIBUTING.rst index f6acb40e782d..b79cc9dbcd01 100644 --- a/packages/grafeas/CONTRIBUTING.rst +++ b/packages/grafeas/CONTRIBUTING.rst @@ -22,7 +22,7 @@ In order to add a feature: documentation. - The feature must work fully on the following CPython versions: - 3.7, 3.8, 3.9, 3.10, 3.11 and 3.12 on both UNIX and Windows. + 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13 on both UNIX and Windows. - The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should @@ -72,7 +72,7 @@ We use `nox `__ to instrument our tests. - To run a single unit test:: - $ nox -s unit-3.12 -- -k + $ nox -s unit-3.13 -- -k .. note:: @@ -143,12 +143,12 @@ Running System Tests $ nox -s system # Run a single system test - $ nox -s system-3.12 -- -k + $ nox -s system-3.13 -- -k .. note:: - System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11 and 3.12. + System tests are only configured to run under Python 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13. For expediency, we do not run them in older versions of Python 3. This alone will not run the tests. You'll need to change some local @@ -227,6 +227,7 @@ We support: - `Python 3.10`_ - `Python 3.11`_ - `Python 3.12`_ +- `Python 3.13`_ .. _Python 3.7: https://docs.python.org/3.7/ .. _Python 3.8: https://docs.python.org/3.8/ @@ -234,6 +235,7 @@ We support: .. _Python 3.10: https://docs.python.org/3.10/ .. _Python 3.11: https://docs.python.org/3.11/ .. _Python 3.12: https://docs.python.org/3.12/ +.. _Python 3.13: https://docs.python.org/3.13/ Supported versions can be found in our ``noxfile.py`` `config`_. diff --git a/packages/grafeas/MANIFEST.in b/packages/grafeas/MANIFEST.in index e0a66705318e..d6814cd60037 100644 --- a/packages/grafeas/MANIFEST.in +++ b/packages/grafeas/MANIFEST.in @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/grafeas/docs/conf.py b/packages/grafeas/docs/conf.py index 5ca427b2aedc..26d3833a8757 100644 --- a/packages/grafeas/docs/conf.py +++ b/packages/grafeas/docs/conf.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest.py index 461bc835d063..4403a5301af3 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/rest.py @@ -42,7 +42,7 @@ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, grpc_version=None, - rest_version=requests_version, + rest_version=f"requests@{requests_version}", ) diff --git a/packages/grafeas/noxfile.py b/packages/grafeas/noxfile.py index 35fd05608ec5..62a0480d833f 100644 --- a/packages/grafeas/noxfile.py +++ b/packages/grafeas/noxfile.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -35,7 +35,15 @@ DEFAULT_PYTHON_VERSION = "3.10" -UNIT_TEST_PYTHON_VERSIONS: List[str] = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] +UNIT_TEST_PYTHON_VERSIONS: List[str] = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", +] UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", "asyncmock", @@ -49,7 +57,7 @@ UNIT_TEST_EXTRAS: List[str] = [] UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} -SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12"] +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] SYSTEM_TEST_STANDARD_DEPENDENCIES = [ "mock", "pytest", @@ -168,7 +176,7 @@ def install_unittest_dependencies(session, *constraints): def unit(session, protobuf_implementation): # Install all test dependencies, then install this package in-place. - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"): + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): session.skip("cpp implementation is not supported in python 3.11+") constraints_path = str( @@ -368,7 +376,7 @@ def docfx(session): ) -@nox.session(python="3.12") +@nox.session(python="3.13") @nox.parametrize( "protobuf_implementation", ["python", "upb", "cpp"], @@ -376,7 +384,7 @@ def docfx(session): def prerelease_deps(session, protobuf_implementation): """Run all tests with prerelease versions of dependencies installed.""" - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"): + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): session.skip("cpp implementation is not supported in python 3.11+") # Install all dependencies diff --git a/packages/grafeas/scripts/decrypt-secrets.sh b/packages/grafeas/scripts/decrypt-secrets.sh index 0018b421ddf8..120b0ddc4364 100755 --- a/packages/grafeas/scripts/decrypt-secrets.sh +++ b/packages/grafeas/scripts/decrypt-secrets.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2023 Google LLC All rights reserved. +# Copyright 2024 Google LLC All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/grafeas/setup.py b/packages/grafeas/setup.py index 96236b6dcd35..70bf18c4b933 100644 --- a/packages/grafeas/setup.py +++ b/packages/grafeas/setup.py @@ -44,6 +44,7 @@ # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0", "proto-plus >= 1.22.3, <2.0.0dev", + "proto-plus >= 1.25.0, <2.0.0dev; python_version >= '3.13'", "protobuf>=3.20.2,<6.0.0dev,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", ] extras = {} @@ -82,6 +83,7 @@ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "Topic :: Internet", ], diff --git a/owl-bot-staging/grafeas/v1/testing/constraints-3.13.txt b/packages/grafeas/testing/constraints-3.13.txt similarity index 100% rename from owl-bot-staging/grafeas/v1/testing/constraints-3.13.txt rename to packages/grafeas/testing/constraints-3.13.txt