From 27380f8946c91dbcde42bdc7dd38bf0dfad5646e Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Thu, 1 Jul 2021 16:36:05 -0400 Subject: [PATCH] chore: migrate to owl bot (#75) * chore: migrate to owl bot * copy code from googleapis-gen * run the post processor --- packages/grafeas/.coveragerc | 6 +- packages/grafeas/.flake8 | 1 + packages/grafeas/.github/.OwlBot.lock.yaml | 3 + packages/grafeas/.github/.OwlBot.yaml | 26 + .../grafeas/.github/header-checker-lint.yml | 15 + packages/grafeas/.kokoro/build.sh | 18 +- packages/grafeas/.kokoro/docs/common.cfg | 2 +- .../grafeas/.kokoro/docs/docs-presubmit.cfg | 11 + packages/grafeas/.kokoro/populate-secrets.sh | 43 + packages/grafeas/.kokoro/release.sh | 4 +- packages/grafeas/.kokoro/release/common.cfg | 42 +- .../.kokoro/samples/python3.6/common.cfg | 6 + .../samples/python3.6/periodic-head.cfg | 11 + .../.kokoro/samples/python3.7/common.cfg | 6 + .../samples/python3.7/periodic-head.cfg | 11 + .../.kokoro/samples/python3.8/common.cfg | 6 + .../samples/python3.8/periodic-head.cfg | 11 + .../.kokoro/samples/python3.9/common.cfg | 40 + .../.kokoro/samples/python3.9/continuous.cfg | 6 + .../samples/python3.9/periodic-head.cfg | 11 + .../.kokoro/samples/python3.9/periodic.cfg | 6 + .../.kokoro/samples/python3.9/presubmit.cfg | 6 + .../.kokoro/test-samples-against-head.sh | 28 + packages/grafeas/.kokoro/test-samples-impl.sh | 102 ++ packages/grafeas/.kokoro/test-samples.sh | 90 +- packages/grafeas/.kokoro/trampoline.sh | 15 +- packages/grafeas/.pre-commit-config.yaml | 31 + packages/grafeas/.trampolinerc | 1 + packages/grafeas/CODE_OF_CONDUCT.md | 123 +- packages/grafeas/CONTRIBUTING.rst | 85 +- packages/grafeas/LICENSE | 7 +- packages/grafeas/MANIFEST.in | 4 +- packages/grafeas/docs/_static/custom.css | 18 +- packages/grafeas/docs/conf.py | 27 +- packages/grafeas/docs/grafeas_v1/grafeas.rst | 10 + packages/grafeas/docs/grafeas_v1/services.rst | 6 +- packages/grafeas/docs/grafeas_v1/types.rst | 2 + packages/grafeas/docs/multiprocessing.rst | 4 +- packages/grafeas/grafeas/grafeas/__init__.py | 76 +- .../grafeas/grafeas/grafeas_v1/__init__.py | 13 +- .../grafeas/grafeas_v1/gapic_metadata.json | 163 ++ .../grafeas/grafeas_v1/services/__init__.py | 1 - .../grafeas_v1/services/grafeas/__init__.py | 2 - .../services/grafeas/async_client.py | 292 ++-- .../grafeas_v1/services/grafeas/client.py | 302 ++-- .../grafeas_v1/services/grafeas/pagers.py | 67 +- .../services/grafeas/transports/__init__.py | 3 - .../services/grafeas/transports/base.py | 236 ++- .../services/grafeas/transports/grpc.py | 171 +- .../grafeas/transports/grpc_asyncio.py | 149 +- .../grafeas/grafeas_v1/types/__init__.py | 177 +- .../grafeas/grafeas_v1/types/attestation.py | 12 +- .../grafeas/grafeas/grafeas_v1/types/build.py | 10 +- .../grafeas/grafeas_v1/types/common.py | 12 +- .../grafeas/grafeas/grafeas_v1/types/cvss.py | 34 +- .../grafeas/grafeas_v1/types/deployment.py | 33 +- .../grafeas/grafeas_v1/types/discovery.py | 31 +- .../grafeas/grafeas_v1/types/grafeas.py | 244 ++- .../grafeas/grafeas/grafeas_v1/types/image.py | 37 +- .../grafeas/grafeas_v1/types/package.py | 57 +- .../grafeas/grafeas_v1/types/provenance.py | 154 +- .../grafeas/grafeas_v1/types/upgrade.py | 76 +- .../grafeas/grafeas_v1/types/vulnerability.py | 127 +- packages/grafeas/noxfile.py | 64 +- packages/grafeas/{synth.py => owlbot.py} | 181 +-- packages/grafeas/renovate.json | 6 +- packages/grafeas/scripts/decrypt-secrets.sh | 15 +- .../scripts/fixup_grafeas_v1_keywords.py | 34 +- packages/grafeas/setup.py | 2 +- packages/grafeas/synth.metadata | 37 - packages/grafeas/testing/constraints-3.6.txt | 5 +- packages/grafeas/tests/__init__.py | 15 + packages/grafeas/tests/unit/__init__.py | 15 + packages/grafeas/tests/unit/gapic/__init__.py | 15 + .../tests/unit/gapic/grafeas_v1/__init__.py | 16 +- .../unit/gapic/grafeas_v1/test_grafeas.py | 1422 +++++++++++------ 76 files changed, 3091 insertions(+), 2059 deletions(-) create mode 100644 packages/grafeas/.github/.OwlBot.lock.yaml create mode 100644 packages/grafeas/.github/.OwlBot.yaml create mode 100644 packages/grafeas/.github/header-checker-lint.yml create mode 100755 packages/grafeas/.kokoro/populate-secrets.sh create mode 100644 packages/grafeas/.kokoro/samples/python3.6/periodic-head.cfg create mode 100644 packages/grafeas/.kokoro/samples/python3.7/periodic-head.cfg create mode 100644 packages/grafeas/.kokoro/samples/python3.8/periodic-head.cfg create mode 100644 packages/grafeas/.kokoro/samples/python3.9/common.cfg create mode 100644 packages/grafeas/.kokoro/samples/python3.9/continuous.cfg create mode 100644 packages/grafeas/.kokoro/samples/python3.9/periodic-head.cfg create mode 100644 packages/grafeas/.kokoro/samples/python3.9/periodic.cfg create mode 100644 packages/grafeas/.kokoro/samples/python3.9/presubmit.cfg create mode 100755 packages/grafeas/.kokoro/test-samples-against-head.sh create mode 100755 packages/grafeas/.kokoro/test-samples-impl.sh create mode 100644 packages/grafeas/.pre-commit-config.yaml create mode 100644 packages/grafeas/docs/grafeas_v1/grafeas.rst create mode 100644 packages/grafeas/grafeas/grafeas_v1/gapic_metadata.json rename packages/grafeas/{synth.py => owlbot.py} (54%) delete mode 100644 packages/grafeas/synth.metadata create mode 100644 packages/grafeas/tests/__init__.py create mode 100644 packages/grafeas/tests/unit/__init__.py create mode 100644 packages/grafeas/tests/unit/gapic/__init__.py diff --git a/packages/grafeas/.coveragerc b/packages/grafeas/.coveragerc index a336e0799b98..e61907768908 100644 --- a/packages/grafeas/.coveragerc +++ b/packages/grafeas/.coveragerc @@ -2,9 +2,9 @@ branch = True [report] -fail_under = 100 show_missing = True -omit = grafeas/__init__.py +omit = + grafeas/grafeas/__init__.py exclude_lines = # Re-enable the standard pragma pragma: NO COVER @@ -14,4 +14,4 @@ exclude_lines = # This is added at the module level as a safeguard for if someone # generates the code and tries to run it without pip installing. This # makes it virtually impossible to test properly. - except pkg_resources.DistributionNotFound \ No newline at end of file + except pkg_resources.DistributionNotFound diff --git a/packages/grafeas/.flake8 b/packages/grafeas/.flake8 index ed9316381c9c..29227d4cf419 100644 --- a/packages/grafeas/.flake8 +++ b/packages/grafeas/.flake8 @@ -26,6 +26,7 @@ exclude = *_pb2.py # Standard linting exemptions. + **/.nox/** __pycache__, .git, *.pyc, diff --git a/packages/grafeas/.github/.OwlBot.lock.yaml b/packages/grafeas/.github/.OwlBot.lock.yaml new file mode 100644 index 000000000000..13aba710159f --- /dev/null +++ b/packages/grafeas/.github/.OwlBot.lock.yaml @@ -0,0 +1,3 @@ +docker: + digest: sha256:99d90d097e4a4710cc8658ee0b5b963f4426d0e424819787c3ac1405c9a26719 + image: gcr.io/repo-automation-bots/owlbot-python:latest diff --git a/packages/grafeas/.github/.OwlBot.yaml b/packages/grafeas/.github/.OwlBot.yaml new file mode 100644 index 000000000000..6f0af6556800 --- /dev/null +++ b/packages/grafeas/.github/.OwlBot.yaml @@ -0,0 +1,26 @@ +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +docker: + image: gcr.io/repo-automation-bots/owlbot-python:latest + +deep-remove-regex: + - /owl-bot-staging + +deep-copy-regex: + - source: /grafeas/(v.*)/.*-py/(.*) + dest: /owl-bot-staging/$1/$2 + +begin-after-commit-hash: de97bb0aeade880aba2cd71a55c06dbc4cd2b337 + diff --git a/packages/grafeas/.github/header-checker-lint.yml b/packages/grafeas/.github/header-checker-lint.yml new file mode 100644 index 000000000000..6fe78aa7987a --- /dev/null +++ b/packages/grafeas/.github/header-checker-lint.yml @@ -0,0 +1,15 @@ +{"allowedCopyrightHolders": ["Google LLC"], + "allowedLicenses": ["Apache-2.0", "MIT", "BSD-3"], + "ignoreFiles": ["**/requirements.txt", "**/requirements-test.txt", "**/__init__.py", "samples/**/constraints.txt", "samples/**/constraints-test.txt"], + "sourceFileExtensions": [ + "ts", + "js", + "java", + "sh", + "Dockerfile", + "yaml", + "py", + "html", + "txt" + ] +} \ No newline at end of file diff --git a/packages/grafeas/.kokoro/build.sh b/packages/grafeas/.kokoro/build.sh index 70d037c5da3c..ac828ec06822 100755 --- a/packages/grafeas/.kokoro/build.sh +++ b/packages/grafeas/.kokoro/build.sh @@ -15,7 +15,11 @@ set -eo pipefail -cd github/python-grafeas +if [[ -z "${PROJECT_ROOT:-}" ]]; then + PROJECT_ROOT="github/python-grafeas" +fi + +cd "${PROJECT_ROOT}" # Disable buffering, so that the logs stream through. export PYTHONUNBUFFERED=1 @@ -30,11 +34,11 @@ export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json export PROJECT_ID=$(cat "${KOKORO_GFILE_DIR}/project-id.json") # Remove old nox -python3.6 -m pip uninstall --yes --quiet nox-automation +python3 -m pip uninstall --yes --quiet nox-automation # Install nox -python3.6 -m pip install --upgrade --quiet nox -python3.6 -m nox --version +python3 -m pip install --upgrade --quiet nox +python3 -m nox --version # If this is a continuous build, send the test log to the FlakyBot. # See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. @@ -49,7 +53,7 @@ fi # If NOX_SESSION is set, it only runs the specified session, # otherwise run all the sessions. if [[ -n "${NOX_SESSION:-}" ]]; then - python3.6 -m nox -s "${NOX_SESSION:-}" + python3 -m nox -s ${NOX_SESSION:-} else - python3.6 -m nox -fi \ No newline at end of file + python3 -m nox +fi diff --git a/packages/grafeas/.kokoro/docs/common.cfg b/packages/grafeas/.kokoro/docs/common.cfg index 8f7afcd12080..969ebd14eb03 100644 --- a/packages/grafeas/.kokoro/docs/common.cfg +++ b/packages/grafeas/.kokoro/docs/common.cfg @@ -30,7 +30,7 @@ env_vars: { env_vars: { key: "V2_STAGING_BUCKET" - value: "docs-staging-v2-staging" + value: "docs-staging-v2" } # It will upload the docker image after successful builds. diff --git a/packages/grafeas/.kokoro/docs/docs-presubmit.cfg b/packages/grafeas/.kokoro/docs/docs-presubmit.cfg index 1118107829b7..d828df6846ad 100644 --- a/packages/grafeas/.kokoro/docs/docs-presubmit.cfg +++ b/packages/grafeas/.kokoro/docs/docs-presubmit.cfg @@ -15,3 +15,14 @@ env_vars: { key: "TRAMPOLINE_IMAGE_UPLOAD" value: "false" } + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-grafeas/.kokoro/build.sh" +} + +# Only run this nox session. +env_vars: { + key: "NOX_SESSION" + value: "docs docfx" +} diff --git a/packages/grafeas/.kokoro/populate-secrets.sh b/packages/grafeas/.kokoro/populate-secrets.sh new file mode 100755 index 000000000000..f52514257ef0 --- /dev/null +++ b/packages/grafeas/.kokoro/populate-secrets.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eo pipefail + +function now { date +"%Y-%m-%d %H:%M:%S" | tr -d '\n' ;} +function msg { println "$*" >&2 ;} +function println { printf '%s\n' "$(now) $*" ;} + + +# Populates requested secrets set in SECRET_MANAGER_KEYS from service account: +# kokoro-trampoline@cloud-devrel-kokoro-resources.iam.gserviceaccount.com +SECRET_LOCATION="${KOKORO_GFILE_DIR}/secret_manager" +msg "Creating folder on disk for secrets: ${SECRET_LOCATION}" +mkdir -p ${SECRET_LOCATION} +for key in $(echo ${SECRET_MANAGER_KEYS} | sed "s/,/ /g") +do + msg "Retrieving secret ${key}" + docker run --entrypoint=gcloud \ + --volume=${KOKORO_GFILE_DIR}:${KOKORO_GFILE_DIR} \ + gcr.io/google.com/cloudsdktool/cloud-sdk \ + secrets versions access latest \ + --project cloud-devrel-kokoro-resources \ + --secret ${key} > \ + "${SECRET_LOCATION}/${key}" + if [[ $? == 0 ]]; then + msg "Secret written to ${SECRET_LOCATION}/${key}" + else + msg "Error retrieving secret ${key}" + fi +done diff --git a/packages/grafeas/.kokoro/release.sh b/packages/grafeas/.kokoro/release.sh index 9b7a96df577c..0aef91d29ed5 100755 --- a/packages/grafeas/.kokoro/release.sh +++ b/packages/grafeas/.kokoro/release.sh @@ -26,7 +26,7 @@ python3 -m pip install --upgrade twine wheel setuptools export PYTHONUNBUFFERED=1 # Move into the package, build the distribution and upload. -TWINE_PASSWORD=$(cat "${KOKORO_KEYSTORE_DIR}/73713_google_cloud_pypi_password") +TWINE_PASSWORD=$(cat "${KOKORO_GFILE_DIR}/secret_manager/google-cloud-pypi-token") cd github/python-grafeas python3 setup.py sdist bdist_wheel -twine upload --username gcloudpypi --password "${TWINE_PASSWORD}" dist/* +twine upload --username __token__ --password "${TWINE_PASSWORD}" dist/* diff --git a/packages/grafeas/.kokoro/release/common.cfg b/packages/grafeas/.kokoro/release/common.cfg index 933870cbe3af..cde7007731a7 100644 --- a/packages/grafeas/.kokoro/release/common.cfg +++ b/packages/grafeas/.kokoro/release/common.cfg @@ -23,42 +23,8 @@ env_vars: { value: "github/python-grafeas/.kokoro/release.sh" } -# Fetch the token needed for reporting release status to GitHub -before_action { - fetch_keystore { - keystore_resource { - keystore_config_id: 73713 - keyname: "yoshi-automation-github-key" - } - } -} - -# Fetch PyPI password -before_action { - fetch_keystore { - keystore_resource { - keystore_config_id: 73713 - keyname: "google_cloud_pypi_password" - } - } -} - -# Fetch magictoken to use with Magic Github Proxy -before_action { - fetch_keystore { - keystore_resource { - keystore_config_id: 73713 - keyname: "releasetool-magictoken" - } - } -} - -# Fetch api key to use with Magic Github Proxy -before_action { - fetch_keystore { - keystore_resource { - keystore_config_id: 73713 - keyname: "magic-github-proxy-api-key" - } - } +# Tokens needed to report release status back to GitHub +env_vars: { + key: "SECRET_MANAGER_KEYS" + value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem,google-cloud-pypi-token" } diff --git a/packages/grafeas/.kokoro/samples/python3.6/common.cfg b/packages/grafeas/.kokoro/samples/python3.6/common.cfg index 321eeec1368b..154ee7c802fb 100644 --- a/packages/grafeas/.kokoro/samples/python3.6/common.cfg +++ b/packages/grafeas/.kokoro/samples/python3.6/common.cfg @@ -13,6 +13,12 @@ env_vars: { value: "py-3.6" } +# Declare build specific Cloud project. +env_vars: { + key: "BUILD_SPECIFIC_GCLOUD_PROJECT" + value: "python-docs-samples-tests-py36" +} + env_vars: { key: "TRAMPOLINE_BUILD_FILE" value: "github/python-grafeas/.kokoro/test-samples.sh" diff --git a/packages/grafeas/.kokoro/samples/python3.6/periodic-head.cfg b/packages/grafeas/.kokoro/samples/python3.6/periodic-head.cfg new file mode 100644 index 000000000000..f9cfcd33e058 --- /dev/null +++ b/packages/grafeas/.kokoro/samples/python3.6/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/packages/grafeas/.kokoro/samples/python3.7/common.cfg b/packages/grafeas/.kokoro/samples/python3.7/common.cfg index 301533d52d2c..e9b9ad84c4e2 100644 --- a/packages/grafeas/.kokoro/samples/python3.7/common.cfg +++ b/packages/grafeas/.kokoro/samples/python3.7/common.cfg @@ -13,6 +13,12 @@ env_vars: { value: "py-3.7" } +# Declare build specific Cloud project. +env_vars: { + key: "BUILD_SPECIFIC_GCLOUD_PROJECT" + value: "python-docs-samples-tests-py37" +} + env_vars: { key: "TRAMPOLINE_BUILD_FILE" value: "github/python-grafeas/.kokoro/test-samples.sh" diff --git a/packages/grafeas/.kokoro/samples/python3.7/periodic-head.cfg b/packages/grafeas/.kokoro/samples/python3.7/periodic-head.cfg new file mode 100644 index 000000000000..f9cfcd33e058 --- /dev/null +++ b/packages/grafeas/.kokoro/samples/python3.7/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/packages/grafeas/.kokoro/samples/python3.8/common.cfg b/packages/grafeas/.kokoro/samples/python3.8/common.cfg index fe1ee7dbfee8..e104dad90806 100644 --- a/packages/grafeas/.kokoro/samples/python3.8/common.cfg +++ b/packages/grafeas/.kokoro/samples/python3.8/common.cfg @@ -13,6 +13,12 @@ env_vars: { value: "py-3.8" } +# Declare build specific Cloud project. +env_vars: { + key: "BUILD_SPECIFIC_GCLOUD_PROJECT" + value: "python-docs-samples-tests-py38" +} + env_vars: { key: "TRAMPOLINE_BUILD_FILE" value: "github/python-grafeas/.kokoro/test-samples.sh" diff --git a/packages/grafeas/.kokoro/samples/python3.8/periodic-head.cfg b/packages/grafeas/.kokoro/samples/python3.8/periodic-head.cfg new file mode 100644 index 000000000000..f9cfcd33e058 --- /dev/null +++ b/packages/grafeas/.kokoro/samples/python3.8/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/packages/grafeas/.kokoro/samples/python3.9/common.cfg b/packages/grafeas/.kokoro/samples/python3.9/common.cfg new file mode 100644 index 000000000000..ddd1a2c98495 --- /dev/null +++ b/packages/grafeas/.kokoro/samples/python3.9/common.cfg @@ -0,0 +1,40 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "py-3.9" +} + +# Declare build specific Cloud project. +env_vars: { + key: "BUILD_SPECIFIC_GCLOUD_PROJECT" + value: "python-docs-samples-tests-py39" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-grafeas/.kokoro/test-samples.sh" +} + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" +} + +# Download secrets for samples +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "python-grafeas/.kokoro/trampoline.sh" \ No newline at end of file diff --git a/packages/grafeas/.kokoro/samples/python3.9/continuous.cfg b/packages/grafeas/.kokoro/samples/python3.9/continuous.cfg new file mode 100644 index 000000000000..a1c8d9759c88 --- /dev/null +++ b/packages/grafeas/.kokoro/samples/python3.9/continuous.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/packages/grafeas/.kokoro/samples/python3.9/periodic-head.cfg b/packages/grafeas/.kokoro/samples/python3.9/periodic-head.cfg new file mode 100644 index 000000000000..f9cfcd33e058 --- /dev/null +++ b/packages/grafeas/.kokoro/samples/python3.9/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/packages/grafeas/.kokoro/samples/python3.9/periodic.cfg b/packages/grafeas/.kokoro/samples/python3.9/periodic.cfg new file mode 100644 index 000000000000..50fec9649732 --- /dev/null +++ b/packages/grafeas/.kokoro/samples/python3.9/periodic.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "False" +} \ No newline at end of file diff --git a/packages/grafeas/.kokoro/samples/python3.9/presubmit.cfg b/packages/grafeas/.kokoro/samples/python3.9/presubmit.cfg new file mode 100644 index 000000000000..a1c8d9759c88 --- /dev/null +++ b/packages/grafeas/.kokoro/samples/python3.9/presubmit.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/packages/grafeas/.kokoro/test-samples-against-head.sh b/packages/grafeas/.kokoro/test-samples-against-head.sh new file mode 100755 index 000000000000..e6f436a6de8c --- /dev/null +++ b/packages/grafeas/.kokoro/test-samples-against-head.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# 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. + +# A customized test runner for samples. +# +# For periodic builds, you can specify this file for testing against head. + +# `-e` enables the script to automatically fail when a command fails +# `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero +set -eo pipefail +# Enables `**` to include files nested inside sub-folders +shopt -s globstar + +cd github/python-grafeas + +exec .kokoro/test-samples-impl.sh diff --git a/packages/grafeas/.kokoro/test-samples-impl.sh b/packages/grafeas/.kokoro/test-samples-impl.sh new file mode 100755 index 000000000000..cf5de74c17a5 --- /dev/null +++ b/packages/grafeas/.kokoro/test-samples-impl.sh @@ -0,0 +1,102 @@ +#!/bin/bash +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.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. + + +# `-e` enables the script to automatically fail when a command fails +# `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero +set -eo pipefail +# Enables `**` to include files nested inside sub-folders +shopt -s globstar + +# Exit early if samples directory doesn't exist +if [ ! -d "./samples" ]; then + echo "No tests run. `./samples` not found" + exit 0 +fi + +# Disable buffering, so that the logs stream through. +export PYTHONUNBUFFERED=1 + +# Debug: show build environment +env | grep KOKORO + +# Install nox +python3.6 -m pip install --upgrade --quiet nox + +# Use secrets acessor service account to get secrets +if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then + gcloud auth activate-service-account \ + --key-file="${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" \ + --project="cloud-devrel-kokoro-resources" +fi + +# This script will create 3 files: +# - testing/test-env.sh +# - testing/service-account.json +# - testing/client-secrets.json +./scripts/decrypt-secrets.sh + +source ./testing/test-env.sh +export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/testing/service-account.json + +# For cloud-run session, we activate the service account for gcloud sdk. +gcloud auth activate-service-account \ + --key-file "${GOOGLE_APPLICATION_CREDENTIALS}" + +export GOOGLE_CLIENT_SECRETS=$(pwd)/testing/client-secrets.json + +echo -e "\n******************** TESTING PROJECTS ********************" + +# Switch to 'fail at end' to allow all tests to complete before exiting. +set +e +# Use RTN to return a non-zero value if the test fails. +RTN=0 +ROOT=$(pwd) +# Find all requirements.txt in the samples directory (may break on whitespace). +for file in samples/**/requirements.txt; do + cd "$ROOT" + # Navigate to the project folder. + file=$(dirname "$file") + cd "$file" + + echo "------------------------------------------------------------" + echo "- testing $file" + echo "------------------------------------------------------------" + + # Use nox to execute the tests for the project. + python3.6 -m nox -s "$RUN_TESTS_SESSION" + EXIT=$? + + # If this is a periodic build, send the test log to the FlakyBot. + # See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. + if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then + chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot + $KOKORO_GFILE_DIR/linux_amd64/flakybot + fi + + if [[ $EXIT -ne 0 ]]; then + RTN=1 + echo -e "\n Testing failed: Nox returned a non-zero exit code. \n" + else + echo -e "\n Testing completed.\n" + fi + +done +cd "$ROOT" + +# Workaround for Kokoro permissions issue: delete secrets +rm testing/{test-env.sh,client-secrets.json,service-account.json} + +exit "$RTN" diff --git a/packages/grafeas/.kokoro/test-samples.sh b/packages/grafeas/.kokoro/test-samples.sh index ed40aab47c4a..ab655c864af5 100755 --- a/packages/grafeas/.kokoro/test-samples.sh +++ b/packages/grafeas/.kokoro/test-samples.sh @@ -13,6 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +# The default test runner for samples. +# +# For periodic builds, we rewinds the repo to the latest release, and +# run test-samples-impl.sh. # `-e` enables the script to automatically fail when a command fails # `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero @@ -24,81 +28,19 @@ cd github/python-grafeas # Run periodic samples tests at latest release if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then + # preserving the test runner implementation. + cp .kokoro/test-samples-impl.sh "${TMPDIR}/test-samples-impl.sh" + echo "--- IMPORTANT IMPORTANT IMPORTANT ---" + echo "Now we rewind the repo back to the latest release..." LATEST_RELEASE=$(git describe --abbrev=0 --tags) git checkout $LATEST_RELEASE -fi - -# Disable buffering, so that the logs stream through. -export PYTHONUNBUFFERED=1 - -# Debug: show build environment -env | grep KOKORO - -# Install nox -python3.6 -m pip install --upgrade --quiet nox - -# Use secrets acessor service account to get secrets -if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then - gcloud auth activate-service-account \ - --key-file="${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" \ - --project="cloud-devrel-kokoro-resources" -fi - -# This script will create 3 files: -# - testing/test-env.sh -# - testing/service-account.json -# - testing/client-secrets.json -./scripts/decrypt-secrets.sh - -source ./testing/test-env.sh -export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/testing/service-account.json - -# For cloud-run session, we activate the service account for gcloud sdk. -gcloud auth activate-service-account \ - --key-file "${GOOGLE_APPLICATION_CREDENTIALS}" - -export GOOGLE_CLIENT_SECRETS=$(pwd)/testing/client-secrets.json - -echo -e "\n******************** TESTING PROJECTS ********************" - -# Switch to 'fail at end' to allow all tests to complete before exiting. -set +e -# Use RTN to return a non-zero value if the test fails. -RTN=0 -ROOT=$(pwd) -# Find all requirements.txt in the samples directory (may break on whitespace). -for file in samples/**/requirements.txt; do - cd "$ROOT" - # Navigate to the project folder. - file=$(dirname "$file") - cd "$file" - - echo "------------------------------------------------------------" - echo "- testing $file" - echo "------------------------------------------------------------" - - # Use nox to execute the tests for the project. - python3.6 -m nox -s "$RUN_TESTS_SESSION" - EXIT=$? - - # If this is a periodic build, send the test log to the FlakyBot. - # See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. - if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then - chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot - $KOKORO_GFILE_DIR/linux_amd64/flakybot + echo "The current head is: " + echo $(git rev-parse --verify HEAD) + echo "--- IMPORTANT IMPORTANT IMPORTANT ---" + # move back the test runner implementation if there's no file. + if [ ! -f .kokoro/test-samples-impl.sh ]; then + cp "${TMPDIR}/test-samples-impl.sh" .kokoro/test-samples-impl.sh fi +fi - if [[ $EXIT -ne 0 ]]; then - RTN=1 - echo -e "\n Testing failed: Nox returned a non-zero exit code. \n" - else - echo -e "\n Testing completed.\n" - fi - -done -cd "$ROOT" - -# Workaround for Kokoro permissions issue: delete secrets -rm testing/{test-env.sh,client-secrets.json,service-account.json} - -exit "$RTN" \ No newline at end of file +exec .kokoro/test-samples-impl.sh diff --git a/packages/grafeas/.kokoro/trampoline.sh b/packages/grafeas/.kokoro/trampoline.sh index e8c4251f3ed4..f39236e943a8 100755 --- a/packages/grafeas/.kokoro/trampoline.sh +++ b/packages/grafeas/.kokoro/trampoline.sh @@ -15,9 +15,14 @@ set -eo pipefail -python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" || ret_code=$? +# Always run the cleanup script, regardless of the success of bouncing into +# the container. +function cleanup() { + chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh + ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh + echo "cleanup"; +} +trap cleanup EXIT -chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh -${KOKORO_GFILE_DIR}/trampoline_cleanup.sh || true - -exit ${ret_code} +$(dirname $0)/populate-secrets.sh # Secret Manager secrets. +python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" \ No newline at end of file diff --git a/packages/grafeas/.pre-commit-config.yaml b/packages/grafeas/.pre-commit-config.yaml new file mode 100644 index 000000000000..62eb5a77d9a3 --- /dev/null +++ b/packages/grafeas/.pre-commit-config.yaml @@ -0,0 +1,31 @@ +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.0.1 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml +- repo: https://github.com/psf/black + rev: 19.10b0 + hooks: + - id: black +- repo: https://gitlab.com/pycqa/flake8 + rev: 3.9.2 + hooks: + - id: flake8 diff --git a/packages/grafeas/.trampolinerc b/packages/grafeas/.trampolinerc index 995ee29111e1..383b6ec89fbc 100644 --- a/packages/grafeas/.trampolinerc +++ b/packages/grafeas/.trampolinerc @@ -24,6 +24,7 @@ required_envvars+=( pass_down_envvars+=( "STAGING_BUCKET" "V2_STAGING_BUCKET" + "NOX_SESSION" ) # Prevent unintentional override on the default image. diff --git a/packages/grafeas/CODE_OF_CONDUCT.md b/packages/grafeas/CODE_OF_CONDUCT.md index b3d1f6029849..039f43681204 100644 --- a/packages/grafeas/CODE_OF_CONDUCT.md +++ b/packages/grafeas/CODE_OF_CONDUCT.md @@ -1,44 +1,95 @@ -# Contributor Code of Conduct +# Code of Conduct -As contributors and maintainers of this project, -and in the interest of fostering an open and welcoming community, -we pledge to respect all people who contribute through reporting issues, -posting feature requests, updating documentation, -submitting pull requests or patches, and other activities. +## Our Pledge -We are committed to making participation in this project -a harassment-free experience for everyone, -regardless of level of experience, gender, gender identity and expression, -sexual orientation, disability, personal appearance, -body size, race, ethnicity, age, religion, or nationality. +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of +experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members Examples of unacceptable behavior by participants include: -* The use of sexualized language or imagery -* Personal attacks -* Trolling or insulting/derogatory comments -* Public or private harassment -* Publishing other's private information, -such as physical or electronic -addresses, without explicit permission -* Other unethical or unprofessional conduct. +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct. -By adopting this Code of Conduct, -project maintainers commit themselves to fairly and consistently -applying these principles to every aspect of managing this project. -Project maintainers who do not follow or enforce the Code of Conduct -may be permanently removed from the project team. - -This code of conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. - -Instances of abusive, harassing, or otherwise unacceptable behavior -may be reported by opening an issue -or contacting one or more of the project maintainers. - -This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, -available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, +offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +This Code of Conduct also applies outside the project spaces when the Project +Steward has a reasonable belief that an individual's behavior may have a +negative impact on the project or its community. + +## Conflict Resolution + +We do not believe that all conflict is bad; healthy debate and disagreement +often yield positive results. However, it is never okay to be disrespectful or +to engage in behavior that violates the project’s code of conduct. + +If you see someone violating the code of conduct, you are encouraged to address +the behavior directly with those involved. Many issues can be resolved quickly +and easily, and this gives people more control over the outcome of their +dispute. If you are unable to resolve the matter for any reason, or if the +behavior is threatening or harassing, report it. We are dedicated to providing +an environment where participants feel welcome and safe. + + +Reports should be directed to *googleapis-stewards@google.com*, the +Project Steward(s) for *Google Cloud Client Libraries*. It is the Project Steward’s duty to +receive and address reported violations of the code of conduct. They will then +work with a committee consisting of representatives from the Open Source +Programs Office and the Google Open Source Strategy team. If for any reason you +are uncomfortable reaching out to the Project Steward, please email +opensource@google.com. + +We will investigate every complaint, but you may not receive a direct response. +We will use our discretion in determining when and how to follow up on reported +incidents, which may range from not taking action to permanent expulsion from +the project and project-sponsored spaces. We will notify the accused of the +report and provide them an opportunity to discuss it before any action is taken. +The identity of the reporter will be omitted from the details of the report +supplied to the accused. In potentially harmful situations, such as ongoing +harassment or threats to anyone's safety, we may take action without notice. + +## Attribution + +This Code of Conduct is adapted from the Contributor Covenant, version 1.4, +available at +https://www.contributor-covenant.org/version/1/4/code-of-conduct.html \ No newline at end of file diff --git a/packages/grafeas/CONTRIBUTING.rst b/packages/grafeas/CONTRIBUTING.rst index f6bf1b7c1ca0..85399205694a 100644 --- a/packages/grafeas/CONTRIBUTING.rst +++ b/packages/grafeas/CONTRIBUTING.rst @@ -21,8 +21,8 @@ In order to add a feature: - The feature must be documented in both the API and narrative documentation. -- The feature must work fully on the following CPython versions: 2.7, - 3.5, 3.6, 3.7 and 3.8 on both UNIX and Windows. +- The feature must work fully on the following CPython versions: + 3.6, 3.7, 3.8 and 3.9 on both UNIX and Windows. - The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should @@ -68,10 +68,12 @@ Using ``nox`` We use `nox `__ to instrument our tests. - To test your changes, run unit tests with ``nox``:: + $ nox -s unit + +- To run a single unit test:: + + $ nox -s unit-3.9 -- -k - $ nox -s unit-2.7 - $ nox -s unit-3.7 - $ ... .. note:: @@ -80,25 +82,6 @@ We use `nox `__ to instrument our tests. .. nox: https://pypi.org/project/nox/ -Note on Editable Installs / Develop Mode -======================================== - -- As mentioned previously, using ``setuptools`` in `develop mode`_ - or a ``pip`` `editable install`_ is not possible with this - library. This is because this library uses `namespace packages`_. - For context see `Issue #2316`_ and the relevant `PyPA issue`_. - - Since ``editable`` / ``develop`` mode can't be used, packages - need to be installed directly. Hence your changes to the source - tree don't get incorporated into the **already installed** - package. - -.. _namespace packages: https://www.python.org/dev/peps/pep-0420/ -.. _Issue #2316: https://github.com/GoogleCloudPlatform/google-cloud-python/issues/2316 -.. _PyPA issue: https://github.com/pypa/packaging-problems/issues/12 -.. _develop mode: https://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode -.. _editable install: https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs - ***************************************** I'm getting weird errors... Can you help? ***************************************** @@ -112,8 +95,12 @@ On Debian/Ubuntu:: ************ Coding Style ************ +- We use the automatic code formatter ``black``. You can run it using + the nox session ``blacken``. This will eliminate many lint errors. Run via:: -- PEP8 compliance, with exceptions defined in the linter configuration. + $ nox -s blacken + +- PEP8 compliance is required, with exceptions defined in the linter configuration. If you have ``nox`` installed, you can test that you have not introduced any non-compliant code via:: @@ -130,6 +117,16 @@ Coding Style should point to the official ``googleapis`` checkout and the the branch should be the main branch on that remote (``master``). +- This repository contains configuration for the + `pre-commit `__ tool, which automates checking + our linters during a commit. If you have it installed on your ``$PATH``, + you can enable enforcing those checks via: + +.. code-block:: bash + + $ pre-commit install + pre-commit installed at .git/hooks/pre-commit + Exceptions to PEP8: - Many unit tests use a helper method, ``_call_fut`` ("FUT" is short for @@ -142,34 +139,23 @@ Running System Tests - To run system tests, you can execute:: - $ nox -s system-3.7 - $ nox -s system-2.7 + # Run all system tests + $ nox -s system + + # Run a single system test + $ nox -s system-3.8 -- -k + .. note:: - System tests are only configured to run under Python 2.7 and - Python 3.7. For expediency, we do not run them in older versions - of Python 3. + System tests are only configured to run under Python 3.8. + 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 auth settings and change some configuration in your project to run all the tests. -- System tests will be run against an actual project and - so you'll need to provide some environment variables to facilitate - authentication to your project: - - - ``GOOGLE_APPLICATION_CREDENTIALS``: The path to a JSON key file; - Such a file can be downloaded directly from the developer's console by clicking - "Generate new JSON key". See private key - `docs `__ - for more details. - -- Once you have downloaded your json keys, set the environment variable - ``GOOGLE_APPLICATION_CREDENTIALS`` to the absolute path of the json file:: - - $ export GOOGLE_APPLICATION_CREDENTIALS="/Users//path/to/app_credentials.json" - +- System tests will be run against an actual project. You should use local credentials from gcloud when possible. See `Best practices for application authentication `__. Some tests require a service account. For those tests see `Authenticating as a service account `__. ************* Test Coverage @@ -211,25 +197,24 @@ Supported Python Versions We support: -- `Python 3.5`_ - `Python 3.6`_ - `Python 3.7`_ - `Python 3.8`_ +- `Python 3.9`_ -.. _Python 3.5: https://docs.python.org/3.5/ .. _Python 3.6: https://docs.python.org/3.6/ .. _Python 3.7: https://docs.python.org/3.7/ .. _Python 3.8: https://docs.python.org/3.8/ +.. _Python 3.9: https://docs.python.org/3.9/ Supported versions can be found in our ``noxfile.py`` `config`_. .. _config: https://github.com/googleapis/python-grafeas/blob/master/noxfile.py -Python 2.7 support is deprecated. All code changes should maintain Python 2.7 compatibility until January 1, 2020. -We also explicitly decided to support Python 3 beginning with version -3.5. Reasons for this include: +We also explicitly decided to support Python 3 beginning with version 3.6. +Reasons for this include: - Encouraging use of newest versions of Python 3 - Taking the lead of `prominent`_ open-source `projects`_ diff --git a/packages/grafeas/LICENSE b/packages/grafeas/LICENSE index a8ee855de2aa..d64569567334 100644 --- a/packages/grafeas/LICENSE +++ b/packages/grafeas/LICENSE @@ -1,6 +1,7 @@ - Apache License + + Apache License Version 2.0, January 2004 - https://www.apache.org/licenses/ + http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -192,7 +193,7 @@ 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 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/packages/grafeas/MANIFEST.in b/packages/grafeas/MANIFEST.in index e9e29d12033d..e783f4c6209b 100644 --- a/packages/grafeas/MANIFEST.in +++ b/packages/grafeas/MANIFEST.in @@ -16,10 +16,10 @@ # Generated by synthtool. DO NOT EDIT! include README.rst LICENSE -recursive-include google *.json *.proto +recursive-include google *.json *.proto py.typed recursive-include tests * global-exclude *.py[co] global-exclude __pycache__ # Exclude scripts for samples readmegen -prune scripts/readme-gen \ No newline at end of file +prune scripts/readme-gen diff --git a/packages/grafeas/docs/_static/custom.css b/packages/grafeas/docs/_static/custom.css index 0abaf229fce3..b0a295464b23 100644 --- a/packages/grafeas/docs/_static/custom.css +++ b/packages/grafeas/docs/_static/custom.css @@ -1,4 +1,20 @@ div#python2-eol { border-color: red; border-width: medium; -} \ No newline at end of file +} + +/* Ensure minimum width for 'Parameters' / 'Returns' column */ +dl.field-list > dt { + min-width: 100px +} + +/* Insert space between methods for readability */ +dl.method { + padding-top: 10px; + padding-bottom: 10px +} + +/* Insert empty space between classes */ +dl.class { + padding-bottom: 50px +} diff --git a/packages/grafeas/docs/conf.py b/packages/grafeas/docs/conf.py index 3251d2801dcb..3a50c5af7103 100644 --- a/packages/grafeas/docs/conf.py +++ b/packages/grafeas/docs/conf.py @@ -1,4 +1,17 @@ # -*- coding: utf-8 -*- +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 # @@ -67,9 +80,9 @@ master_doc = "index" # General information about the project. -project = u"grafeas" -copyright = u"2019, Google" -author = u"Google APIs" +project = "grafeas" +copyright = "2019, Google" +author = "Google APIs" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -265,7 +278,7 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, "grafeas.tex", u"grafeas Documentation", author, "manual",) + (master_doc, "grafeas.tex", "grafeas Documentation", author, "manual",) ] # The name of an image file (relative to this directory) to place at the top of @@ -293,7 +306,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [(master_doc, "grafeas", u"grafeas Documentation", [author], 1,)] +man_pages = [(master_doc, "grafeas", "grafeas Documentation", [author], 1,)] # If true, show URL addresses after external links. # man_show_urls = False @@ -308,7 +321,7 @@ ( master_doc, "grafeas", - u"grafeas Documentation", + "grafeas Documentation", author, "grafeas", "grafeas Library", @@ -335,6 +348,8 @@ "google-auth": ("https://googleapis.dev/python/google-auth/latest/", None), "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None,), "grpc": ("https://grpc.github.io/grpc/python/", None), + "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), } diff --git a/packages/grafeas/docs/grafeas_v1/grafeas.rst b/packages/grafeas/docs/grafeas_v1/grafeas.rst new file mode 100644 index 000000000000..7339fabecaee --- /dev/null +++ b/packages/grafeas/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/packages/grafeas/docs/grafeas_v1/services.rst b/packages/grafeas/docs/grafeas_v1/services.rst index 0d27b7e2d0d7..ca38222018ff 100644 --- a/packages/grafeas/docs/grafeas_v1/services.rst +++ b/packages/grafeas/docs/grafeas_v1/services.rst @@ -1,6 +1,6 @@ Services for Grafeas Grafeas v1 API =================================== +.. toctree:: + :maxdepth: 2 -.. automodule:: grafeas.grafeas_v1.services.grafeas - :members: - :inherited-members: + grafeas diff --git a/packages/grafeas/docs/grafeas_v1/types.rst b/packages/grafeas/docs/grafeas_v1/types.rst index 0d2ca040a55b..91237ff546fc 100644 --- a/packages/grafeas/docs/grafeas_v1/types.rst +++ b/packages/grafeas/docs/grafeas_v1/types.rst @@ -3,3 +3,5 @@ Types for Grafeas Grafeas v1 API .. automodule:: grafeas.grafeas_v1.types :members: + :undoc-members: + :show-inheritance: diff --git a/packages/grafeas/docs/multiprocessing.rst b/packages/grafeas/docs/multiprocessing.rst index 1cb29d4ca967..536d17b2ea65 100644 --- a/packages/grafeas/docs/multiprocessing.rst +++ b/packages/grafeas/docs/multiprocessing.rst @@ -1,7 +1,7 @@ .. note:: - Because this client uses :mod:`grpcio` library, it is safe to + Because this client uses :mod:`grpc` library, it is safe to share instances across threads. In multiprocessing scenarios, the best practice is to create client instances *after* the invocation of - :func:`os.fork` by :class:`multiprocessing.Pool` or + :func:`os.fork` by :class:`multiprocessing.pool.Pool` or :class:`multiprocessing.Process`. diff --git a/packages/grafeas/grafeas/grafeas/__init__.py b/packages/grafeas/grafeas/grafeas/__init__.py index 7f69a2782a7e..b88e2f22316b 100644 --- a/packages/grafeas/grafeas/grafeas/__init__.py +++ b/packages/grafeas/grafeas/grafeas/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,15 +14,16 @@ # limitations under the License. # -from grafeas.grafeas_v1.services.grafeas.async_client import GrafeasAsyncClient 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.build import BuildNote from grafeas.grafeas_v1.types.build import BuildOccurrence -from grafeas.grafeas_v1.types.common import NoteKind 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.cvss import CVSSv3 from grafeas.grafeas_v1.types.deployment import DeploymentNote from grafeas.grafeas_v1.types.deployment import DeploymentOccurrence @@ -54,12 +54,12 @@ 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.package import Architecture 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 @@ -77,74 +77,74 @@ 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.vulnerability import Severity from grafeas.grafeas_v1.types.vulnerability import VulnerabilityNote from grafeas.grafeas_v1.types.vulnerability import VulnerabilityOccurrence +from grafeas.grafeas_v1.types.vulnerability import Severity __all__ = ( - "AliasContext", - "Architecture", - "Artifact", + "GrafeasClient", + "GrafeasAsyncClient", "AttestationNote", "AttestationOccurrence", + "BuildNote", + "BuildOccurrence", + "RelatedUrl", + "Signature", + "NoteKind", + "CVSSv3", + "DeploymentNote", + "DeploymentOccurrence", + "DiscoveryNote", + "DiscoveryOccurrence", "BatchCreateNotesRequest", "BatchCreateNotesResponse", "BatchCreateOccurrencesRequest", "BatchCreateOccurrencesResponse", - "BuildNote", - "BuildOccurrence", - "BuildProvenance", - "CVSSv3", - "CloudRepoSourceContext", - "Command", "CreateNoteRequest", "CreateOccurrenceRequest", "DeleteNoteRequest", "DeleteOccurrenceRequest", - "DeploymentNote", - "DeploymentOccurrence", - "DiscoveryNote", - "DiscoveryOccurrence", - "Distribution", - "FileHashes", - "Fingerprint", - "GerritSourceContext", "GetNoteRequest", "GetOccurrenceNoteRequest", "GetOccurrenceRequest", - "GitSourceContext", - "GrafeasAsyncClient", - "GrafeasClient", - "Hash", - "ImageNote", - "ImageOccurrence", - "Layer", "ListNoteOccurrencesRequest", "ListNoteOccurrencesResponse", "ListNotesRequest", "ListNotesResponse", "ListOccurrencesRequest", "ListOccurrencesResponse", - "Location", "Note", - "NoteKind", "Occurrence", + "UpdateNoteRequest", + "UpdateOccurrenceRequest", + "Fingerprint", + "ImageNote", + "ImageOccurrence", + "Layer", + "Distribution", + "Location", "PackageNote", "PackageOccurrence", + "Version", + "Architecture", + "AliasContext", + "Artifact", + "BuildProvenance", + "CloudRepoSourceContext", + "Command", + "FileHashes", + "GerritSourceContext", + "GitSourceContext", + "Hash", "ProjectRepoId", - "RelatedUrl", "RepoId", - "Severity", - "Signature", "Source", "SourceContext", - "UpdateNoteRequest", - "UpdateOccurrenceRequest", "UpgradeDistribution", "UpgradeNote", "UpgradeOccurrence", - "Version", + "WindowsUpdate", "VulnerabilityNote", "VulnerabilityOccurrence", - "WindowsUpdate", + "Severity", ) diff --git a/packages/grafeas/grafeas/grafeas_v1/__init__.py b/packages/grafeas/grafeas/grafeas_v1/__init__.py index 98e1ad1c8c28..e6c64a104a31 100644 --- a/packages/grafeas/grafeas/grafeas_v1/__init__.py +++ b/packages/grafeas/grafeas/grafeas_v1/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,13 +15,15 @@ # from .services.grafeas import GrafeasClient +from .services.grafeas import GrafeasAsyncClient + from .types.attestation import AttestationNote from .types.attestation import AttestationOccurrence from .types.build import BuildNote from .types.build import BuildOccurrence -from .types.common import NoteKind from .types.common import RelatedUrl from .types.common import Signature +from .types.common import NoteKind from .types.cvss import CVSSv3 from .types.deployment import DeploymentNote from .types.deployment import DeploymentOccurrence @@ -53,12 +54,12 @@ from .types.image import ImageNote from .types.image import ImageOccurrence from .types.image import Layer -from .types.package import Architecture 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 @@ -76,12 +77,12 @@ from .types.upgrade import UpgradeNote from .types.upgrade import UpgradeOccurrence from .types.upgrade import WindowsUpdate -from .types.vulnerability import Severity from .types.vulnerability import VulnerabilityNote from .types.vulnerability import VulnerabilityOccurrence - +from .types.vulnerability import Severity __all__ = ( + "GrafeasAsyncClient", "AliasContext", "Architecture", "Artifact", @@ -113,6 +114,7 @@ "GetOccurrenceNoteRequest", "GetOccurrenceRequest", "GitSourceContext", + "GrafeasClient", "Hash", "ImageNote", "ImageOccurrence", @@ -145,5 +147,4 @@ "VulnerabilityNote", "VulnerabilityOccurrence", "WindowsUpdate", - "GrafeasClient", ) diff --git a/packages/grafeas/grafeas/grafeas_v1/gapic_metadata.json b/packages/grafeas/grafeas/grafeas_v1/gapic_metadata.json new file mode 100644 index 000000000000..77f5ac0fca4d --- /dev/null +++ b/packages/grafeas/grafeas/grafeas_v1/gapic_metadata.json @@ -0,0 +1,163 @@ + { + "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" + ] + } + } + } + } + } + } +} diff --git a/packages/grafeas/grafeas/grafeas_v1/services/__init__.py b/packages/grafeas/grafeas/grafeas_v1/services/__init__.py index 42ffdf2bc43d..4de65971c238 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/__init__.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/__init__.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/__init__.py index d06e1144ae94..00f191521c60 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/__init__.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .client import GrafeasClient from .async_client import GrafeasAsyncClient diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/async_client.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/async_client.py index fc42be2bde8c..e79a88088378 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/async_client.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/async_client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict import functools import re @@ -22,14 +20,14 @@ import pkg_resources import google.api_core.client_options as ClientOptions # type: ignore -from google.api_core import exceptions # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore -from google.protobuf import field_mask_pb2 as field_mask # type: ignore -from google.protobuf import timestamp_pb2 as timestamp # 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 @@ -41,8 +39,7 @@ from grafeas.grafeas_v1.types import package from grafeas.grafeas_v1.types import upgrade from grafeas.grafeas_v1.types import vulnerability - -from .transports.base import GrafeasTransport +from .transports.base import GrafeasTransport, DEFAULT_CLIENT_INFO from .transports.grpc_asyncio import GrafeasGrpcAsyncIOTransport from .client import GrafeasClient @@ -68,12 +65,52 @@ class GrafeasAsyncClient: _client: GrafeasClient - DEFAULT_ENDPOINT = GrafeasClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = GrafeasClient.DEFAULT_MTLS_ENDPOINT - + 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) - note_path = staticmethod(GrafeasClient.note_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 + + @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 get_transport_class = functools.partial( type(GrafeasClient).get_transport_class, type(GrafeasClient) @@ -107,15 +144,15 @@ async def get_occurrence( r"""Gets the specified occurrence. Args: - request (:class:`~.grafeas.GetOccurrenceRequest`): + request (:class:`grafeas.grafeas_v1.types.GetOccurrenceRequest`): 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.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -123,7 +160,7 @@ async def get_occurrence( sent along with the request as metadata. Returns: - ~.grafeas.Occurrence: + grafeas.grafeas_v1.types.Occurrence: An instance of an analysis type that has been found on a resource. @@ -131,7 +168,8 @@ async def get_occurrence( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + 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." @@ -141,7 +179,6 @@ async def get_occurrence( # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -154,11 +191,13 @@ async def get_occurrence( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -186,11 +225,12 @@ async def list_occurrences( r"""Lists occurrences for the specified project. Args: - request (:class:`~.grafeas.ListOccurrencesRequest`): + request (:class:`grafeas.grafeas_v1.types.ListOccurrencesRequest`): 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. @@ -199,7 +239,6 @@ async def list_occurrences( 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. @@ -207,7 +246,7 @@ async def list_occurrences( sent along with the request as metadata. Returns: - ~.pagers.ListOccurrencesAsyncPager: + grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesAsyncPager: Response for listing occurrences. Iterating over this object will yield results and resolve additional pages @@ -217,7 +256,8 @@ async def list_occurrences( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent, filter]): + 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." @@ -227,7 +267,6 @@ async def list_occurrences( # 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: @@ -242,11 +281,13 @@ async def list_occurrences( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -281,15 +322,15 @@ async def delete_occurrence( is no longer applicable for the given resource. Args: - request (:class:`~.grafeas.DeleteOccurrenceRequest`): + request (:class:`grafeas.grafeas_v1.types.DeleteOccurrenceRequest`): 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.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -299,7 +340,8 @@ async def delete_occurrence( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + 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." @@ -309,7 +351,6 @@ async def delete_occurrence( # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -322,11 +363,13 @@ async def delete_occurrence( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -353,21 +396,21 @@ async def create_occurrence( r"""Creates a new occurrence. Args: - request (:class:`~.grafeas.CreateOccurrenceRequest`): + request (:class:`grafeas.grafeas_v1.types.CreateOccurrenceRequest`): 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.Occurrence`): + 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.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -375,7 +418,7 @@ async def create_occurrence( sent along with the request as metadata. Returns: - ~.grafeas.Occurrence: + grafeas.grafeas_v1.types.Occurrence: An instance of an analysis type that has been found on a resource. @@ -383,7 +426,8 @@ async def create_occurrence( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent, occurrence]): + 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." @@ -393,7 +437,6 @@ async def create_occurrence( # 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: @@ -404,7 +447,7 @@ async def create_occurrence( rpc = gapic_v1.method_async.wrap_method( self._client._transport.create_occurrence, default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -432,23 +475,24 @@ async def batch_create_occurrences( r"""Creates new occurrences in batch. Args: - request (:class:`~.grafeas.BatchCreateOccurrencesRequest`): + request (:class:`grafeas.grafeas_v1.types.BatchCreateOccurrencesRequest`): 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:`Sequence[~.grafeas.Occurrence]`): + occurrences (:class:`Sequence[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. @@ -456,7 +500,7 @@ async def batch_create_occurrences( sent along with the request as metadata. Returns: - ~.grafeas.BatchCreateOccurrencesResponse: + grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse: Response for creating occurrences in batch. @@ -464,7 +508,8 @@ async def batch_create_occurrences( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent, occurrences]): + 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." @@ -474,18 +519,17 @@ async def batch_create_occurrences( # 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 + if occurrences: + request.occurrences.extend(occurrences) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.batch_create_occurrences, default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -506,7 +550,7 @@ async def update_occurrence( *, name: str = None, occurrence: grafeas.Occurrence = None, - update_mask: field_mask.FieldMask = None, + update_mask: field_mask_pb2.FieldMask = None, retry: retries.Retry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -514,25 +558,25 @@ async def update_occurrence( r"""Updates the specified occurrence. Args: - request (:class:`~.grafeas.UpdateOccurrenceRequest`): + request (:class:`grafeas.grafeas_v1.types.UpdateOccurrenceRequest`): 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.Occurrence`): + 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:`~.field_mask.FieldMask`): + 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.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -540,7 +584,7 @@ async def update_occurrence( sent along with the request as metadata. Returns: - ~.grafeas.Occurrence: + grafeas.grafeas_v1.types.Occurrence: An instance of an analysis type that has been found on a resource. @@ -548,7 +592,8 @@ async def update_occurrence( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, occurrence, update_mask]): + 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." @@ -558,7 +603,6 @@ async def update_occurrence( # 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: @@ -571,7 +615,7 @@ async def update_occurrence( rpc = gapic_v1.method_async.wrap_method( self._client._transport.update_occurrence, default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -600,16 +644,16 @@ async def get_occurrence_note( belongs to a provider project. Args: - request (:class:`~.grafeas.GetOccurrenceNoteRequest`): + request (:class:`grafeas.grafeas_v1.types.GetOccurrenceNoteRequest`): 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.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -617,7 +661,7 @@ async def get_occurrence_note( sent along with the request as metadata. Returns: - ~.grafeas.Note: + grafeas.grafeas_v1.types.Note: A type of analysis that can be done for a resource. @@ -625,7 +669,8 @@ async def get_occurrence_note( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + 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." @@ -635,7 +680,6 @@ async def get_occurrence_note( # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -648,11 +692,13 @@ async def get_occurrence_note( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -679,15 +725,15 @@ async def get_note( r"""Gets the specified note. Args: - request (:class:`~.grafeas.GetNoteRequest`): + request (:class:`grafeas.grafeas_v1.types.GetNoteRequest`): 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.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -695,7 +741,7 @@ async def get_note( sent along with the request as metadata. Returns: - ~.grafeas.Note: + grafeas.grafeas_v1.types.Note: A type of analysis that can be done for a resource. @@ -703,7 +749,8 @@ async def get_note( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + 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." @@ -713,7 +760,6 @@ async def get_note( # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -726,11 +772,13 @@ async def get_note( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -758,11 +806,12 @@ async def list_notes( r"""Lists notes for the specified project. Args: - request (:class:`~.grafeas.ListNotesRequest`): + request (:class:`grafeas.grafeas_v1.types.ListNotesRequest`): 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. @@ -771,7 +820,6 @@ async def list_notes( 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. @@ -779,7 +827,7 @@ async def list_notes( sent along with the request as metadata. Returns: - ~.pagers.ListNotesAsyncPager: + grafeas.grafeas_v1.services.grafeas.pagers.ListNotesAsyncPager: Response for listing notes. Iterating over this object will yield results and resolve additional pages @@ -789,7 +837,8 @@ async def list_notes( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent, filter]): + 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." @@ -799,7 +848,6 @@ async def list_notes( # 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: @@ -814,11 +862,13 @@ async def list_notes( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -851,15 +901,15 @@ async def delete_note( r"""Deletes the specified note. Args: - request (:class:`~.grafeas.DeleteNoteRequest`): + request (:class:`grafeas.grafeas_v1.types.DeleteNoteRequest`): 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.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -869,7 +919,8 @@ async def delete_note( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name]): + 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." @@ -879,7 +930,6 @@ async def delete_note( # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -892,11 +942,13 @@ async def delete_note( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -924,12 +976,13 @@ async def create_note( r"""Creates a new note. Args: - request (:class:`~.grafeas.CreateNoteRequest`): + request (:class:`grafeas.grafeas_v1.types.CreateNoteRequest`): 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. @@ -938,12 +991,11 @@ async def create_note( This corresponds to the ``note_id`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - note (:class:`~.grafeas.Note`): + 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.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -951,7 +1003,7 @@ async def create_note( sent along with the request as metadata. Returns: - ~.grafeas.Note: + grafeas.grafeas_v1.types.Note: A type of analysis that can be done for a resource. @@ -959,7 +1011,8 @@ async def create_note( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent, note_id, note]): + 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." @@ -969,7 +1022,6 @@ async def create_note( # 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: @@ -982,7 +1034,7 @@ async def create_note( rpc = gapic_v1.method_async.wrap_method( self._client._transport.create_note, default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -1010,22 +1062,23 @@ async def batch_create_notes( r"""Creates new notes in batch. Args: - request (:class:`~.grafeas.BatchCreateNotesRequest`): + request (:class:`grafeas.grafeas_v1.types.BatchCreateNotesRequest`): 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:`Sequence[~.grafeas.BatchCreateNotesRequest.NotesEntry]`): + notes (:class:`Sequence[grafeas.grafeas_v1.types.BatchCreateNotesRequest.NotesEntry]`): 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. @@ -1033,13 +1086,14 @@ async def batch_create_notes( sent along with the request as metadata. Returns: - ~.grafeas.BatchCreateNotesResponse: + grafeas.grafeas_v1.types.BatchCreateNotesResponse: Response for creating notes in batch. """ # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([parent, notes]): + 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." @@ -1049,18 +1103,18 @@ async def batch_create_notes( # 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 + + if notes: + request.notes.update(notes) # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. rpc = gapic_v1.method_async.wrap_method( self._client._transport.batch_create_notes, default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -1081,7 +1135,7 @@ async def update_note( *, name: str = None, note: grafeas.Note = None, - update_mask: field_mask.FieldMask = None, + update_mask: field_mask_pb2.FieldMask = None, retry: retries.Retry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -1089,25 +1143,25 @@ async def update_note( r"""Updates the specified note. Args: - request (:class:`~.grafeas.UpdateNoteRequest`): + request (:class:`grafeas.grafeas_v1.types.UpdateNoteRequest`): 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.Note`): + 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:`~.field_mask.FieldMask`): + 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.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1115,7 +1169,7 @@ async def update_note( sent along with the request as metadata. Returns: - ~.grafeas.Note: + grafeas.grafeas_v1.types.Note: A type of analysis that can be done for a resource. @@ -1123,7 +1177,8 @@ async def update_note( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, note, update_mask]): + 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." @@ -1133,7 +1188,6 @@ async def update_note( # 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: @@ -1146,7 +1200,7 @@ async def update_note( rpc = gapic_v1.method_async.wrap_method( self._client._transport.update_note, default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -1177,12 +1231,13 @@ async def list_note_occurrences( specified note. Args: - request (:class:`~.grafeas.ListNoteOccurrencesRequest`): + request (:class:`grafeas.grafeas_v1.types.ListNoteOccurrencesRequest`): 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. @@ -1191,7 +1246,6 @@ async def list_note_occurrences( 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. @@ -1199,7 +1253,7 @@ async def list_note_occurrences( sent along with the request as metadata. Returns: - ~.pagers.ListNoteOccurrencesAsyncPager: + grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesAsyncPager: Response for listing occurrences for a note. Iterating over this object will yield @@ -1210,7 +1264,8 @@ async def list_note_occurrences( # Create or coerce a protobuf request object. # Sanity check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. - if request is not None and any([name, filter]): + 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." @@ -1220,7 +1275,6 @@ async def list_note_occurrences( # 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: @@ -1235,11 +1289,13 @@ async def list_note_occurrences( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=DEFAULT_CLIENT_INFO, ) # Certain fields should be provided within the metadata header; @@ -1262,11 +1318,11 @@ async def list_note_occurrences( try: - _client_info = gapic_v1.client_info.ClientInfo( + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=pkg_resources.get_distribution("grafeas",).version, ) except pkg_resources.DistributionNotFound: - _client_info = gapic_v1.client_info.ClientInfo() + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() __all__ = ("GrafeasAsyncClient",) diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/client.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/client.py index 03f388ef875b..569234b506d7 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/client.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,24 +13,25 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict +from distutils import util import os import re -from typing import Callable, Dict, Sequence, Tuple, Type, Union +from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore -from google.api_core import exceptions # type: ignore +from google.api_core import client_options as client_options_lib # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore -from google.auth import credentials # type: ignore +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 -from google.protobuf import field_mask_pb2 as field_mask # type: ignore -from google.protobuf import timestamp_pb2 as timestamp # 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 @@ -43,8 +43,7 @@ from grafeas.grafeas_v1.types import package from grafeas.grafeas_v1.types import upgrade from grafeas.grafeas_v1.types import vulnerability - -from .transports.base import GrafeasTransport +from .transports.base import GrafeasTransport, DEFAULT_CLIENT_INFO from .transports.grpc import GrafeasGrpcTransport from .transports.grpc_asyncio import GrafeasGrpcAsyncIOTransport @@ -62,7 +61,7 @@ class GrafeasClientMeta(type): _transport_registry["grpc_asyncio"] = GrafeasGrpcAsyncIOTransport def get_transport_class(cls, label: str = None,) -> Type[GrafeasTransport]: - """Return an appropriate transport class. + """Returns an appropriate transport class. Args: label: The name of the desired transport. If none is @@ -101,7 +100,8 @@ class GrafeasClient(metaclass=GrafeasClientMeta): @staticmethod def _get_default_mtls_endpoint(api_endpoint): - """Convert api endpoint to mTLS 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: @@ -128,37 +128,129 @@ def _get_default_mtls_endpoint(api_endpoint): return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - DEFAULT_ENDPOINT = "containeranalysis.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GrafeasClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @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: - """Return a fully-qualified note string.""" + """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]: - """Parse a note path into its component segments.""" + """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: - """Return a fully-qualified occurrence string.""" + """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]: - """Parse a occurrence path into its component segments.""" + """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 {} + def __init__(self, *, transport: Union[str, GrafeasTransport] = None,) -> None: """Instantiate the grafeas client. @@ -190,15 +282,15 @@ def get_occurrence( r"""Gets the specified occurrence. Args: - request (:class:`~.grafeas.GetOccurrenceRequest`): + request (grafeas.grafeas_v1.types.GetOccurrenceRequest): The request object. Request to get an occurrence. - name (:class:`str`): + 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. @@ -206,7 +298,7 @@ def get_occurrence( sent along with the request as metadata. Returns: - ~.grafeas.Occurrence: + grafeas.grafeas_v1.types.Occurrence: An instance of an analysis type that has been found on a resource. @@ -227,10 +319,8 @@ def get_occurrence( # there are no flattened fields. 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 @@ -263,20 +353,20 @@ def list_occurrences( r"""Lists occurrences for the specified project. Args: - request (:class:`~.grafeas.ListOccurrencesRequest`): + request (grafeas.grafeas_v1.types.ListOccurrencesRequest): The request object. Request to list occurrences. - parent (:class:`str`): + 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 (:class:`str`): + 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. @@ -284,7 +374,7 @@ def list_occurrences( sent along with the request as metadata. Returns: - ~.pagers.ListOccurrencesPager: + grafeas.grafeas_v1.services.grafeas.pagers.ListOccurrencesPager: Response for listing occurrences. Iterating over this object will yield results and resolve additional pages @@ -307,10 +397,8 @@ def list_occurrences( # there are no flattened fields. 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: @@ -352,15 +440,15 @@ def delete_occurrence( is no longer applicable for the given resource. Args: - request (:class:`~.grafeas.DeleteOccurrenceRequest`): + request (grafeas.grafeas_v1.types.DeleteOccurrenceRequest): The request object. Request to delete an occurrence. - name (:class:`str`): + 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. @@ -383,10 +471,8 @@ def delete_occurrence( # there are no flattened fields. 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 @@ -418,21 +504,21 @@ def create_occurrence( r"""Creates a new occurrence. Args: - request (:class:`~.grafeas.CreateOccurrenceRequest`): + request (grafeas.grafeas_v1.types.CreateOccurrenceRequest): The request object. Request to create a new occurrence. - parent (:class:`str`): + 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 (:class:`~.grafeas.Occurrence`): + 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. @@ -440,7 +526,7 @@ def create_occurrence( sent along with the request as metadata. Returns: - ~.grafeas.Occurrence: + grafeas.grafeas_v1.types.Occurrence: An instance of an analysis type that has been found on a resource. @@ -461,10 +547,8 @@ def create_occurrence( # there are no flattened fields. 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: @@ -499,23 +583,24 @@ def batch_create_occurrences( r"""Creates new occurrences in batch. Args: - request (:class:`~.grafeas.BatchCreateOccurrencesRequest`): + request (grafeas.grafeas_v1.types.BatchCreateOccurrencesRequest): The request object. Request to create occurrences in batch. - parent (:class:`str`): + 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 (:class:`Sequence[~.grafeas.Occurrence]`): + occurrences (Sequence[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. @@ -523,7 +608,7 @@ def batch_create_occurrences( sent along with the request as metadata. Returns: - ~.grafeas.BatchCreateOccurrencesResponse: + grafeas.grafeas_v1.types.BatchCreateOccurrencesResponse: Response for creating occurrences in batch. @@ -544,10 +629,8 @@ def batch_create_occurrences( # there are no flattened fields. 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: @@ -575,7 +658,7 @@ def update_occurrence( *, name: str = None, occurrence: grafeas.Occurrence = None, - update_mask: field_mask.FieldMask = None, + update_mask: field_mask_pb2.FieldMask = None, retry: retries.Retry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -583,25 +666,25 @@ def update_occurrence( r"""Updates the specified occurrence. Args: - request (:class:`~.grafeas.UpdateOccurrenceRequest`): + request (grafeas.grafeas_v1.types.UpdateOccurrenceRequest): The request object. Request to update an occurrence. - name (:class:`str`): + 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 (:class:`~.grafeas.Occurrence`): + 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 (:class:`~.field_mask.FieldMask`): + 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. @@ -609,7 +692,7 @@ def update_occurrence( sent along with the request as metadata. Returns: - ~.grafeas.Occurrence: + grafeas.grafeas_v1.types.Occurrence: An instance of an analysis type that has been found on a resource. @@ -630,10 +713,8 @@ def update_occurrence( # there are no flattened fields. 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: @@ -671,16 +752,16 @@ def get_occurrence_note( belongs to a provider project. Args: - request (:class:`~.grafeas.GetOccurrenceNoteRequest`): + request (grafeas.grafeas_v1.types.GetOccurrenceNoteRequest): The request object. Request to get the note to which the specified occurrence is attached. - name (:class:`str`): + 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. @@ -688,7 +769,7 @@ def get_occurrence_note( sent along with the request as metadata. Returns: - ~.grafeas.Note: + grafeas.grafeas_v1.types.Note: A type of analysis that can be done for a resource. @@ -709,10 +790,8 @@ def get_occurrence_note( # there are no flattened fields. 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 @@ -744,15 +823,15 @@ def get_note( r"""Gets the specified note. Args: - request (:class:`~.grafeas.GetNoteRequest`): + request (grafeas.grafeas_v1.types.GetNoteRequest): The request object. Request to get a note. - name (:class:`str`): + 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. @@ -760,7 +839,7 @@ def get_note( sent along with the request as metadata. Returns: - ~.grafeas.Note: + grafeas.grafeas_v1.types.Note: A type of analysis that can be done for a resource. @@ -781,10 +860,8 @@ def get_note( # there are no flattened fields. 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 @@ -817,20 +894,20 @@ def list_notes( r"""Lists notes for the specified project. Args: - request (:class:`~.grafeas.ListNotesRequest`): + request (grafeas.grafeas_v1.types.ListNotesRequest): The request object. Request to list notes. - parent (:class:`str`): + 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 (:class:`str`): + 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. @@ -838,7 +915,7 @@ def list_notes( sent along with the request as metadata. Returns: - ~.pagers.ListNotesPager: + grafeas.grafeas_v1.services.grafeas.pagers.ListNotesPager: Response for listing notes. Iterating over this object will yield results and resolve additional pages @@ -861,10 +938,8 @@ def list_notes( # there are no flattened fields. 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: @@ -904,15 +979,15 @@ def delete_note( r"""Deletes the specified note. Args: - request (:class:`~.grafeas.DeleteNoteRequest`): + request (grafeas.grafeas_v1.types.DeleteNoteRequest): The request object. Request to delete a note. - name (:class:`str`): + 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. @@ -935,10 +1010,8 @@ def delete_note( # there are no flattened fields. 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 @@ -971,26 +1044,26 @@ def create_note( r"""Creates a new note. Args: - request (:class:`~.grafeas.CreateNoteRequest`): + request (grafeas.grafeas_v1.types.CreateNoteRequest): The request object. Request to create a new note. - parent (:class:`str`): + 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 (:class:`str`): + 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 (:class:`~.grafeas.Note`): + 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. @@ -998,7 +1071,7 @@ def create_note( sent along with the request as metadata. Returns: - ~.grafeas.Note: + grafeas.grafeas_v1.types.Note: A type of analysis that can be done for a resource. @@ -1019,10 +1092,8 @@ def create_note( # there are no flattened fields. 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: @@ -1059,22 +1130,23 @@ def batch_create_notes( r"""Creates new notes in batch. Args: - request (:class:`~.grafeas.BatchCreateNotesRequest`): + request (grafeas.grafeas_v1.types.BatchCreateNotesRequest): The request object. Request to create notes in batch. - parent (:class:`str`): + 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 (:class:`Sequence[~.grafeas.BatchCreateNotesRequest.NotesEntry]`): + notes (Sequence[grafeas.grafeas_v1.types.BatchCreateNotesRequest.NotesEntry]): 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. @@ -1082,7 +1154,7 @@ def batch_create_notes( sent along with the request as metadata. Returns: - ~.grafeas.BatchCreateNotesResponse: + grafeas.grafeas_v1.types.BatchCreateNotesResponse: Response for creating notes in batch. """ # Create or coerce a protobuf request object. @@ -1101,10 +1173,8 @@ def batch_create_notes( # there are no flattened fields. 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: @@ -1132,7 +1202,7 @@ def update_note( *, name: str = None, note: grafeas.Note = None, - update_mask: field_mask.FieldMask = None, + update_mask: field_mask_pb2.FieldMask = None, retry: retries.Retry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), @@ -1140,25 +1210,25 @@ def update_note( r"""Updates the specified note. Args: - request (:class:`~.grafeas.UpdateNoteRequest`): + request (grafeas.grafeas_v1.types.UpdateNoteRequest): The request object. Request to update a note. - name (:class:`str`): + 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 (:class:`~.grafeas.Note`): + 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 (:class:`~.field_mask.FieldMask`): + 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. @@ -1166,7 +1236,7 @@ def update_note( sent along with the request as metadata. Returns: - ~.grafeas.Note: + grafeas.grafeas_v1.types.Note: A type of analysis that can be done for a resource. @@ -1187,10 +1257,8 @@ def update_note( # there are no flattened fields. 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: @@ -1230,21 +1298,21 @@ def list_note_occurrences( specified note. Args: - request (:class:`~.grafeas.ListNoteOccurrencesRequest`): + request (grafeas.grafeas_v1.types.ListNoteOccurrencesRequest): The request object. Request to list occurrences for a note. - name (:class:`str`): + 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 (:class:`str`): + 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. @@ -1252,7 +1320,7 @@ def list_note_occurrences( sent along with the request as metadata. Returns: - ~.pagers.ListNoteOccurrencesPager: + grafeas.grafeas_v1.services.grafeas.pagers.ListNoteOccurrencesPager: Response for listing occurrences for a note. Iterating over this object will yield @@ -1276,10 +1344,8 @@ def list_note_occurrences( # there are no flattened fields. 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: @@ -1309,11 +1375,11 @@ def list_note_occurrences( try: - _client_info = gapic_v1.client_info.ClientInfo( + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=pkg_resources.get_distribution("grafeas",).version, ) except pkg_resources.DistributionNotFound: - _client_info = gapic_v1.client_info.ClientInfo() + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() __all__ = ("GrafeasClient",) diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/pagers.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/pagers.py index 5a9e2293ef3a..7f4c46ac83ec 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/pagers.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/pagers.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,8 +13,16 @@ # See the License for the specific language governing permissions and # limitations under the License. # - -from typing import Any, AsyncIterable, Awaitable, Callable, Iterable, Sequence, Tuple +from typing import ( + Any, + AsyncIterable, + Awaitable, + Callable, + Iterable, + Sequence, + Tuple, + Optional, +) from grafeas.grafeas_v1.types import grafeas @@ -24,7 +31,7 @@ class ListOccurrencesPager: """A pager for iterating through ``list_occurrences`` requests. This class thinly wraps an initial - :class:`~.grafeas.ListOccurrencesResponse` object, and + :class:`grafeas.grafeas_v1.types.ListOccurrencesResponse` object, and provides an ``__iter__`` method to iterate through its ``occurrences`` field. @@ -33,7 +40,7 @@ class ListOccurrencesPager: through the ``occurrences`` field on the corresponding responses. - All the usual :class:`~.grafeas.ListOccurrencesResponse` + 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. """ @@ -51,9 +58,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.grafeas.ListOccurrencesRequest`): + request (grafeas.grafeas_v1.types.ListOccurrencesRequest): The initial request object. - response (:class:`~.grafeas.ListOccurrencesResponse`): + response (grafeas.grafeas_v1.types.ListOccurrencesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -86,7 +93,7 @@ class ListOccurrencesAsyncPager: """A pager for iterating through ``list_occurrences`` requests. This class thinly wraps an initial - :class:`~.grafeas.ListOccurrencesResponse` object, and + :class:`grafeas.grafeas_v1.types.ListOccurrencesResponse` object, and provides an ``__aiter__`` method to iterate through its ``occurrences`` field. @@ -95,7 +102,7 @@ class ListOccurrencesAsyncPager: through the ``occurrences`` field on the corresponding responses. - All the usual :class:`~.grafeas.ListOccurrencesResponse` + 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. """ @@ -108,14 +115,14 @@ def __init__( *, metadata: Sequence[Tuple[str, str]] = () ): - """Instantiate the pager. + """Instantiates the pager. Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.grafeas.ListOccurrencesRequest`): + request (grafeas.grafeas_v1.types.ListOccurrencesRequest): The initial request object. - response (:class:`~.grafeas.ListOccurrencesResponse`): + response (grafeas.grafeas_v1.types.ListOccurrencesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -152,7 +159,7 @@ class ListNotesPager: """A pager for iterating through ``list_notes`` requests. This class thinly wraps an initial - :class:`~.grafeas.ListNotesResponse` object, and + :class:`grafeas.grafeas_v1.types.ListNotesResponse` object, and provides an ``__iter__`` method to iterate through its ``notes`` field. @@ -161,7 +168,7 @@ class ListNotesPager: through the ``notes`` field on the corresponding responses. - All the usual :class:`~.grafeas.ListNotesResponse` + 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. """ @@ -179,9 +186,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.grafeas.ListNotesRequest`): + request (grafeas.grafeas_v1.types.ListNotesRequest): The initial request object. - response (:class:`~.grafeas.ListNotesResponse`): + response (grafeas.grafeas_v1.types.ListNotesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -214,7 +221,7 @@ class ListNotesAsyncPager: """A pager for iterating through ``list_notes`` requests. This class thinly wraps an initial - :class:`~.grafeas.ListNotesResponse` object, and + :class:`grafeas.grafeas_v1.types.ListNotesResponse` object, and provides an ``__aiter__`` method to iterate through its ``notes`` field. @@ -223,7 +230,7 @@ class ListNotesAsyncPager: through the ``notes`` field on the corresponding responses. - All the usual :class:`~.grafeas.ListNotesResponse` + 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. """ @@ -236,14 +243,14 @@ def __init__( *, metadata: Sequence[Tuple[str, str]] = () ): - """Instantiate the pager. + """Instantiates the pager. Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.grafeas.ListNotesRequest`): + request (grafeas.grafeas_v1.types.ListNotesRequest): The initial request object. - response (:class:`~.grafeas.ListNotesResponse`): + response (grafeas.grafeas_v1.types.ListNotesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -280,7 +287,7 @@ class ListNoteOccurrencesPager: """A pager for iterating through ``list_note_occurrences`` requests. This class thinly wraps an initial - :class:`~.grafeas.ListNoteOccurrencesResponse` object, and + :class:`grafeas.grafeas_v1.types.ListNoteOccurrencesResponse` object, and provides an ``__iter__`` method to iterate through its ``occurrences`` field. @@ -289,7 +296,7 @@ class ListNoteOccurrencesPager: through the ``occurrences`` field on the corresponding responses. - All the usual :class:`~.grafeas.ListNoteOccurrencesResponse` + 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. """ @@ -307,9 +314,9 @@ def __init__( Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.grafeas.ListNoteOccurrencesRequest`): + request (grafeas.grafeas_v1.types.ListNoteOccurrencesRequest): The initial request object. - response (:class:`~.grafeas.ListNoteOccurrencesResponse`): + response (grafeas.grafeas_v1.types.ListNoteOccurrencesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. @@ -342,7 +349,7 @@ class ListNoteOccurrencesAsyncPager: """A pager for iterating through ``list_note_occurrences`` requests. This class thinly wraps an initial - :class:`~.grafeas.ListNoteOccurrencesResponse` object, and + :class:`grafeas.grafeas_v1.types.ListNoteOccurrencesResponse` object, and provides an ``__aiter__`` method to iterate through its ``occurrences`` field. @@ -351,7 +358,7 @@ class ListNoteOccurrencesAsyncPager: through the ``occurrences`` field on the corresponding responses. - All the usual :class:`~.grafeas.ListNoteOccurrencesResponse` + 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. """ @@ -364,14 +371,14 @@ def __init__( *, metadata: Sequence[Tuple[str, str]] = () ): - """Instantiate the pager. + """Instantiates the pager. Args: method (Callable): The method that was originally called, and which instantiated this pager. - request (:class:`~.grafeas.ListNoteOccurrencesRequest`): + request (grafeas.grafeas_v1.types.ListNoteOccurrencesRequest): The initial request object. - response (:class:`~.grafeas.ListNoteOccurrencesResponse`): + response (grafeas.grafeas_v1.types.ListNoteOccurrencesResponse): The initial response object. metadata (Sequence[Tuple[str, str]]): Strings which should be sent along with the request as metadata. diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/__init__.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/__init__.py index 6a261fea7bef..e7f5526b4ebf 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/__init__.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from typing import Dict, Type @@ -28,7 +26,6 @@ _transport_registry["grpc"] = GrafeasGrpcTransport _transport_registry["grpc_asyncio"] = GrafeasGrpcAsyncIOTransport - __all__ = ( "GrafeasTransport", "GrafeasGrpcTransport", diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/base.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/base.py index 25ae1ff93e3e..99aa051b8e3b 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/base.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/base.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,27 +13,37 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import abc -import typing +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import packaging.version import pkg_resources -from google import auth -from google.api_core import exceptions # type: ignore +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore -from google.protobuf import empty_pb2 as empty # type: ignore +from google.protobuf import empty_pb2 # type: ignore from grafeas.grafeas_v1.types import grafeas - try: - _client_info = gapic_v1.client_info.ClientInfo( + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( gapic_version=pkg_resources.get_distribution("grafeas",).version, ) except pkg_resources.DistributionNotFound: - _client_info = gapic_v1.client_info.ClientInfo() + DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() + +try: + # google.auth.__version__ was added in 1.26.0 + _GOOGLE_AUTH_VERSION = google.auth.__version__ +except AttributeError: + try: # try pkg_resources if it is available + _GOOGLE_AUTH_VERSION = pkg_resources.get_distribution("google-auth").version + except pkg_resources.DistributionNotFound: # pragma: NO COVER + _GOOGLE_AUTH_VERSION = None class GrafeasTransport(abc.ABC): @@ -42,20 +51,25 @@ class GrafeasTransport(abc.ABC): AUTH_SCOPES = () + DEFAULT_HOST: str = "" + def __init__( self, *, - host: str = "", - credentials: credentials.Credentials = None, - credentials_file: typing.Optional[str] = None, - scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES, - quota_project_id: typing.Optional[str] = None, + host: str = DEFAULT_HOST, + credentials: 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, **kwargs, ) -> None: """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -64,39 +78,79 @@ def __init__( 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. - scope (Optional[Sequence[str]]): A list of scopes. + 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. """ # Save the hostname. Default to port 443 (HTTPS) if none is specified. if ":" not in host: host += ":443" self._host = host + scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + + # Save the scopes. + self._scopes = scopes or self.AUTH_SCOPES + # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: - raise exceptions.DuplicateCredentialArgs( + raise core_exceptions.DuplicateCredentialArgs( "'credentials_file' and 'credentials' are mutually exclusive" ) if credentials_file is not None: - credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) elif credentials is None: - credentials, _ = auth.default( - scopes=scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id ) + # If the credentials is 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 - # Lifted into its own function so it can be stubbed out during tests. - self._prep_wrapped_messages() + # TODO(busunkim): This method is in the base transport + # to avoid duplicating code across the transport classes. These functions + # should be deleted once the minimum required versions of google-auth is increased. + + # TODO: Remove this function once google-auth >= 1.25.0 is required + @classmethod + def _get_scopes_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Optional[Sequence[str]]]: + """Returns scopes kwargs to pass to google-auth methods depending on the google-auth version""" + + scopes_kwargs = {} - def _prep_wrapped_messages(self): + if _GOOGLE_AUTH_VERSION and ( + packaging.version.parse(_GOOGLE_AUTH_VERSION) + >= packaging.version.parse("1.25.0") + ): + scopes_kwargs = {"scopes": scopes, "default_scopes": cls.AUTH_SCOPES} + else: + scopes_kwargs = {"scopes": scopes or cls.AUTH_SCOPES} + + return scopes_kwargs + + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { self.get_occurrence: gapic_v1.method.wrap_method( @@ -106,11 +160,13 @@ def _prep_wrapped_messages(self): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=client_info, ), self.list_occurrences: gapic_v1.method.wrap_method( self.list_occurrences, @@ -119,11 +175,13 @@ def _prep_wrapped_messages(self): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=client_info, ), self.delete_occurrence: gapic_v1.method.wrap_method( self.delete_occurrence, @@ -132,22 +190,24 @@ def _prep_wrapped_messages(self): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=client_info, ), self.create_occurrence: gapic_v1.method.wrap_method( - self.create_occurrence, default_timeout=30.0, client_info=_client_info, + 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, + client_info=client_info, ), self.update_occurrence: gapic_v1.method.wrap_method( - self.update_occurrence, default_timeout=30.0, client_info=_client_info, + self.update_occurrence, default_timeout=30.0, client_info=client_info, ), self.get_occurrence_note: gapic_v1.method.wrap_method( self.get_occurrence_note, @@ -156,11 +216,13 @@ def _prep_wrapped_messages(self): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=client_info, ), self.get_note: gapic_v1.method.wrap_method( self.get_note, @@ -169,11 +231,13 @@ def _prep_wrapped_messages(self): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=client_info, ), self.list_notes: gapic_v1.method.wrap_method( self.list_notes, @@ -182,11 +246,13 @@ def _prep_wrapped_messages(self): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=client_info, ), self.delete_note: gapic_v1.method.wrap_method( self.delete_note, @@ -195,20 +261,22 @@ def _prep_wrapped_messages(self): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=client_info, ), self.create_note: gapic_v1.method.wrap_method( - self.create_note, default_timeout=30.0, client_info=_client_info, + 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.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.update_note, default_timeout=30.0, client_info=client_info, ), self.list_note_occurrences: gapic_v1.method.wrap_method( self.list_note_occurrences, @@ -217,31 +285,32 @@ def _prep_wrapped_messages(self): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), + deadline=30.0, ), default_timeout=30.0, - client_info=_client_info, + client_info=client_info, ), } @property def get_occurrence( self, - ) -> typing.Callable[ + ) -> Callable[ [grafeas.GetOccurrenceRequest], - typing.Union[grafeas.Occurrence, typing.Awaitable[grafeas.Occurrence]], + Union[grafeas.Occurrence, Awaitable[grafeas.Occurrence]], ]: raise NotImplementedError() @property def list_occurrences( self, - ) -> typing.Callable[ + ) -> Callable[ [grafeas.ListOccurrencesRequest], - typing.Union[ - grafeas.ListOccurrencesResponse, - typing.Awaitable[grafeas.ListOccurrencesResponse], + Union[ + grafeas.ListOccurrencesResponse, Awaitable[grafeas.ListOccurrencesResponse] ], ]: raise NotImplementedError() @@ -249,29 +318,29 @@ def list_occurrences( @property def delete_occurrence( self, - ) -> typing.Callable[ + ) -> Callable[ [grafeas.DeleteOccurrenceRequest], - typing.Union[empty.Empty, typing.Awaitable[empty.Empty]], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], ]: raise NotImplementedError() @property def create_occurrence( self, - ) -> typing.Callable[ + ) -> Callable[ [grafeas.CreateOccurrenceRequest], - typing.Union[grafeas.Occurrence, typing.Awaitable[grafeas.Occurrence]], + Union[grafeas.Occurrence, Awaitable[grafeas.Occurrence]], ]: raise NotImplementedError() @property def batch_create_occurrences( self, - ) -> typing.Callable[ + ) -> Callable[ [grafeas.BatchCreateOccurrencesRequest], - typing.Union[ + Union[ grafeas.BatchCreateOccurrencesResponse, - typing.Awaitable[grafeas.BatchCreateOccurrencesResponse], + Awaitable[grafeas.BatchCreateOccurrencesResponse], ], ]: raise NotImplementedError() @@ -279,67 +348,61 @@ def batch_create_occurrences( @property def update_occurrence( self, - ) -> typing.Callable[ + ) -> Callable[ [grafeas.UpdateOccurrenceRequest], - typing.Union[grafeas.Occurrence, typing.Awaitable[grafeas.Occurrence]], + Union[grafeas.Occurrence, Awaitable[grafeas.Occurrence]], ]: raise NotImplementedError() @property def get_occurrence_note( self, - ) -> typing.Callable[ - [grafeas.GetOccurrenceNoteRequest], - typing.Union[grafeas.Note, typing.Awaitable[grafeas.Note]], + ) -> Callable[ + [grafeas.GetOccurrenceNoteRequest], Union[grafeas.Note, Awaitable[grafeas.Note]] ]: raise NotImplementedError() @property def get_note( self, - ) -> typing.Callable[ - [grafeas.GetNoteRequest], - typing.Union[grafeas.Note, typing.Awaitable[grafeas.Note]], + ) -> Callable[ + [grafeas.GetNoteRequest], Union[grafeas.Note, Awaitable[grafeas.Note]] ]: raise NotImplementedError() @property def list_notes( self, - ) -> typing.Callable[ + ) -> Callable[ [grafeas.ListNotesRequest], - typing.Union[ - grafeas.ListNotesResponse, typing.Awaitable[grafeas.ListNotesResponse] - ], + Union[grafeas.ListNotesResponse, Awaitable[grafeas.ListNotesResponse]], ]: raise NotImplementedError() @property def delete_note( self, - ) -> typing.Callable[ - [grafeas.DeleteNoteRequest], - typing.Union[empty.Empty, typing.Awaitable[empty.Empty]], + ) -> Callable[ + [grafeas.DeleteNoteRequest], Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]] ]: raise NotImplementedError() @property def create_note( self, - ) -> typing.Callable[ - [grafeas.CreateNoteRequest], - typing.Union[grafeas.Note, typing.Awaitable[grafeas.Note]], + ) -> Callable[ + [grafeas.CreateNoteRequest], Union[grafeas.Note, Awaitable[grafeas.Note]] ]: raise NotImplementedError() @property def batch_create_notes( self, - ) -> typing.Callable[ + ) -> Callable[ [grafeas.BatchCreateNotesRequest], - typing.Union[ + Union[ grafeas.BatchCreateNotesResponse, - typing.Awaitable[grafeas.BatchCreateNotesResponse], + Awaitable[grafeas.BatchCreateNotesResponse], ], ]: raise NotImplementedError() @@ -347,20 +410,19 @@ def batch_create_notes( @property def update_note( self, - ) -> typing.Callable[ - [grafeas.UpdateNoteRequest], - typing.Union[grafeas.Note, typing.Awaitable[grafeas.Note]], + ) -> Callable[ + [grafeas.UpdateNoteRequest], Union[grafeas.Note, Awaitable[grafeas.Note]] ]: raise NotImplementedError() @property def list_note_occurrences( self, - ) -> typing.Callable[ + ) -> Callable[ [grafeas.ListNoteOccurrencesRequest], - typing.Union[ + Union[ grafeas.ListNoteOccurrencesResponse, - typing.Awaitable[grafeas.ListNoteOccurrencesResponse], + Awaitable[grafeas.ListNoteOccurrencesResponse], ], ]: raise NotImplementedError() diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc.py index e76fe349b664..f4e2ba42a07d 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,21 +13,20 @@ # See the License for the specific language governing permissions and # limitations under the License. # - -from typing import Callable, Dict, Optional, Sequence, Tuple +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import grpc_helpers # type: ignore -from google import auth # type: ignore -from google.auth import credentials # type: ignore +from google.api_core import gapic_v1 # type: ignore +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 as empty # type: ignore +from google.protobuf import empty_pb2 # type: ignore from grafeas.grafeas_v1.types import grafeas - -from .base import GrafeasTransport +from .base import GrafeasTransport, DEFAULT_CLIENT_INFO class GrafeasGrpcTransport(GrafeasTransport): @@ -65,18 +63,22 @@ def __init__( self, *, host: str = "", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Sequence[str] = None, channel: grpc.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, - quota_project_id: Optional[str] = None + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -90,16 +92,27 @@ def __init__( ignored if ``channel`` is provided. channel (Optional[grpc.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + 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 applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): 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. + 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 grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. Raises: google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport @@ -107,69 +120,84 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel - elif api_mtls_endpoint: - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + 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 - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) + 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 + ) - self._stubs = {} # type: Dict[str, Callable] - - # Run the base constructor. + # The base transport sets the host, credentials and scopes super().__init__( host=host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, + scopes=scopes, quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=True, ) + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + 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 = "", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, - **kwargs + **kwargs, ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optionsl[str]): The host for the channel to use. + 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 @@ -192,31 +220,22 @@ def create_channel( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ - scopes = scopes or cls.AUTH_SCOPES + return grpc_helpers.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, - **kwargs + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, ) @property def grpc_channel(self) -> grpc.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 designed to connect to this service. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - - # Return the channel from cache. return self._grpc_channel @property @@ -274,7 +293,7 @@ def list_occurrences( @property def delete_occurrence( self, - ) -> Callable[[grafeas.DeleteOccurrenceRequest], empty.Empty]: + ) -> Callable[[grafeas.DeleteOccurrenceRequest], empty_pb2.Empty]: r"""Return a callable for the delete occurrence method over gRPC. Deletes the specified occurrence. For example, use @@ -295,7 +314,7 @@ def delete_occurrence( self._stubs["delete_occurrence"] = self.grpc_channel.unary_unary( "/grafeas.v1.Grafeas/DeleteOccurrence", request_serializer=grafeas.DeleteOccurrenceRequest.serialize, - response_deserializer=empty.Empty.FromString, + response_deserializer=empty_pb2.Empty.FromString, ) return self._stubs["delete_occurrence"] @@ -458,7 +477,7 @@ def list_notes( return self._stubs["list_notes"] @property - def delete_note(self) -> Callable[[grafeas.DeleteNoteRequest], empty.Empty]: + 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. @@ -477,7 +496,7 @@ def delete_note(self) -> Callable[[grafeas.DeleteNoteRequest], empty.Empty]: self._stubs["delete_note"] = self.grpc_channel.unary_unary( "/grafeas.v1.Grafeas/DeleteNote", request_serializer=grafeas.DeleteNoteRequest.serialize, - response_deserializer=empty.Empty.FromString, + response_deserializer=empty_pb2.Empty.FromString, ) return self._stubs["delete_note"] diff --git a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py index c3318a1b4202..1c61d66e91d6 100644 --- a/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py +++ b/packages/grafeas/grafeas/grafeas_v1/services/grafeas/transports/grpc_asyncio.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,20 +13,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple - +from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +import packaging.version import grpc # type: ignore from grpc.experimental import aio # type: ignore -from google.protobuf import empty_pb2 as empty # type: ignore +from google.protobuf import empty_pb2 # type: ignore from grafeas.grafeas_v1.types import grafeas - -from .base import GrafeasTransport +from .base import GrafeasTransport, DEFAULT_CLIENT_INFO from .grpc import GrafeasGrpcTransport @@ -66,7 +66,7 @@ class GrafeasGrpcAsyncIOTransport(GrafeasTransport): def create_channel( cls, host: str = "", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -74,7 +74,7 @@ def create_channel( ) -> aio.Channel: """Create and return a gRPC AsyncIO channel object. Args: - address (Optional[str]): The host for the channel to use. + 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 @@ -93,13 +93,15 @@ def create_channel( Returns: aio.Channel: A gRPC AsyncIO channel object. """ - scopes = scopes or cls.AUTH_SCOPES + return grpc_helpers_async.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, **kwargs, ) @@ -107,18 +109,22 @@ def __init__( self, *, host: str = "", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, channel: aio.Channel = None, api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, + ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id=None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -133,16 +139,27 @@ def __init__( are passed to :func:`google.auth.default`. channel (Optional[aio.Channel]): A ``Channel`` instance through which to make calls. - api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If - provided, it overrides the ``host`` argument and tries to create + 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 applicatin default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): 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. + 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 grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. Raises: google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport @@ -150,50 +167,69 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) + if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel - elif api_mtls_endpoint: - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + 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 - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials + 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 + ) - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - ) - - # Run the base constructor. + # The base transport sets the host, credentials and scopes super().__init__( host=host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, + scopes=scopes, quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=True, ) - self._stubs = {} + if not self._grpc_channel: + self._grpc_channel = type(self).create_channel( + self._host, + credentials=self._credentials, + credentials_file=credentials_file, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @property def grpc_channel(self) -> aio.Channel: @@ -202,13 +238,6 @@ def grpc_channel(self) -> aio.Channel: This property caches on the instance; repeated calls return the same channel. """ - # Sanity check: Only create a new channel if we do not already - # have one. - if not hasattr(self, "_grpc_channel"): - self._grpc_channel = self.create_channel( - self._host, credentials=self._credentials, - ) - # Return the channel from cache. return self._grpc_channel @@ -269,7 +298,7 @@ def list_occurrences( @property def delete_occurrence( self, - ) -> Callable[[grafeas.DeleteOccurrenceRequest], Awaitable[empty.Empty]]: + ) -> 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 @@ -290,7 +319,7 @@ def delete_occurrence( self._stubs["delete_occurrence"] = self.grpc_channel.unary_unary( "/grafeas.v1.Grafeas/DeleteOccurrence", request_serializer=grafeas.DeleteOccurrenceRequest.serialize, - response_deserializer=empty.Empty.FromString, + response_deserializer=empty_pb2.Empty.FromString, ) return self._stubs["delete_occurrence"] @@ -456,7 +485,7 @@ def list_notes( @property def delete_note( self, - ) -> Callable[[grafeas.DeleteNoteRequest], Awaitable[empty.Empty]]: + ) -> Callable[[grafeas.DeleteNoteRequest], Awaitable[empty_pb2.Empty]]: r"""Return a callable for the delete note method over gRPC. Deletes the specified note. @@ -475,7 +504,7 @@ def delete_note( self._stubs["delete_note"] = self.grpc_channel.unary_unary( "/grafeas.v1.Grafeas/DeleteNote", request_serializer=grafeas.DeleteNoteRequest.serialize, - response_deserializer=empty.Empty.FromString, + response_deserializer=empty_pb2.Empty.FromString, ) return self._stubs["delete_note"] diff --git a/packages/grafeas/grafeas/grafeas_v1/types/__init__.py b/packages/grafeas/grafeas/grafeas_v1/types/__init__.py index e8f115089f83..92060c27fbf1 100644 --- a/packages/grafeas/grafeas/grafeas_v1/types/__init__.py +++ b/packages/grafeas/grafeas/grafeas_v1/types/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,34 +13,19 @@ # See the License for the specific language governing permissions and # limitations under the License. # - -from .common import ( - RelatedUrl, - Signature, -) from .attestation import ( AttestationNote, AttestationOccurrence, ) -from .provenance import ( - BuildProvenance, - Source, - FileHashes, - Hash, - Command, - Artifact, - SourceContext, - AliasContext, - CloudRepoSourceContext, - GerritSourceContext, - GitSourceContext, - RepoId, - ProjectRepoId, -) from .build import ( BuildNote, BuildOccurrence, ) +from .common import ( + RelatedUrl, + Signature, + NoteKind, +) from .cvss import CVSSv3 from .deployment import ( DeploymentNote, @@ -51,11 +35,34 @@ DiscoveryNote, DiscoveryOccurrence, ) +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 ( - Layer, Fingerprint, ImageNote, ImageOccurrence, + Layer, ) from .package import ( Distribution, @@ -63,101 +70,97 @@ PackageNote, PackageOccurrence, Version, + Architecture, +) +from .provenance import ( + AliasContext, + Artifact, + BuildProvenance, + CloudRepoSourceContext, + Command, + FileHashes, + GerritSourceContext, + GitSourceContext, + Hash, + ProjectRepoId, + RepoId, + Source, + SourceContext, ) from .upgrade import ( - UpgradeNote, UpgradeDistribution, - WindowsUpdate, + UpgradeNote, UpgradeOccurrence, + WindowsUpdate, ) from .vulnerability import ( VulnerabilityNote, VulnerabilityOccurrence, -) -from .grafeas import ( - Occurrence, - Note, - GetOccurrenceRequest, - ListOccurrencesRequest, - ListOccurrencesResponse, - DeleteOccurrenceRequest, - CreateOccurrenceRequest, - UpdateOccurrenceRequest, - GetNoteRequest, - GetOccurrenceNoteRequest, - ListNotesRequest, - ListNotesResponse, - DeleteNoteRequest, - CreateNoteRequest, - UpdateNoteRequest, - ListNoteOccurrencesRequest, - ListNoteOccurrencesResponse, - BatchCreateNotesRequest, - BatchCreateNotesResponse, - BatchCreateOccurrencesRequest, - BatchCreateOccurrencesResponse, + Severity, ) - __all__ = ( - "RelatedUrl", - "Signature", "AttestationNote", "AttestationOccurrence", - "BuildProvenance", - "Source", - "FileHashes", - "Hash", - "Command", - "Artifact", - "SourceContext", - "AliasContext", - "CloudRepoSourceContext", - "GerritSourceContext", - "GitSourceContext", - "RepoId", - "ProjectRepoId", "BuildNote", "BuildOccurrence", + "RelatedUrl", + "Signature", + "NoteKind", "CVSSv3", "DeploymentNote", "DeploymentOccurrence", "DiscoveryNote", "DiscoveryOccurrence", - "Layer", + "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", "Distribution", "Location", "PackageNote", "PackageOccurrence", "Version", - "UpgradeNote", + "Architecture", + "AliasContext", + "Artifact", + "BuildProvenance", + "CloudRepoSourceContext", + "Command", + "FileHashes", + "GerritSourceContext", + "GitSourceContext", + "Hash", + "ProjectRepoId", + "RepoId", + "Source", + "SourceContext", "UpgradeDistribution", - "WindowsUpdate", + "UpgradeNote", "UpgradeOccurrence", + "WindowsUpdate", "VulnerabilityNote", "VulnerabilityOccurrence", - "Occurrence", - "Note", - "GetOccurrenceRequest", - "ListOccurrencesRequest", - "ListOccurrencesResponse", - "DeleteOccurrenceRequest", - "CreateOccurrenceRequest", - "UpdateOccurrenceRequest", - "GetNoteRequest", - "GetOccurrenceNoteRequest", - "ListNotesRequest", - "ListNotesResponse", - "DeleteNoteRequest", - "CreateNoteRequest", - "UpdateNoteRequest", - "ListNoteOccurrencesRequest", - "ListNoteOccurrencesResponse", - "BatchCreateNotesRequest", - "BatchCreateNotesResponse", - "BatchCreateOccurrencesRequest", - "BatchCreateOccurrencesResponse", + "Severity", ) diff --git a/packages/grafeas/grafeas/grafeas_v1/types/attestation.py b/packages/grafeas/grafeas/grafeas_v1/types/attestation.py index 693d5b1ea036..0724ee45bce8 100644 --- a/packages/grafeas/grafeas/grafeas_v1/types/attestation.py +++ b/packages/grafeas/grafeas/grafeas_v1/types/attestation.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,10 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - from grafeas.grafeas_v1.types import common @@ -38,7 +35,7 @@ class AttestationNote(proto.Message): don't all live in the same project. Attributes: - hint (~.attestation.AttestationNote.Hint): + hint (grafeas.grafeas_v1.types.AttestationNote.Hint): Hint hints at the purpose of the attestation authority. """ @@ -59,7 +56,7 @@ class Hint(proto.Message): attestation authority, for example "qa". """ - human_readable_name = proto.Field(proto.STRING, number=1) + human_readable_name = proto.Field(proto.STRING, number=1,) hint = proto.Field(proto.MESSAGE, number=1, message=Hint,) @@ -79,7 +76,7 @@ class AttestationOccurrence(proto.Message): serialized_payload (bytes): Required. The serialized payload that is verified by one or more ``signatures``. - signatures (Sequence[~.common.Signature]): + signatures (Sequence[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 @@ -87,8 +84,7 @@ class AttestationOccurrence(proto.Message): for more details on signature structure and verification. """ - serialized_payload = proto.Field(proto.BYTES, number=1) - + serialized_payload = proto.Field(proto.BYTES, number=1,) signatures = proto.RepeatedField(proto.MESSAGE, number=2, message=common.Signature,) diff --git a/packages/grafeas/grafeas/grafeas_v1/types/build.py b/packages/grafeas/grafeas/grafeas_v1/types/build.py index c987d86c46f8..f344a38b218c 100644 --- a/packages/grafeas/grafeas/grafeas_v1/types/build.py +++ b/packages/grafeas/grafeas/grafeas_v1/types/build.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,10 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - from grafeas.grafeas_v1.types import provenance as g_provenance @@ -37,14 +34,14 @@ class BuildNote(proto.Message): which produced this build. """ - builder_version = proto.Field(proto.STRING, number=1) + builder_version = proto.Field(proto.STRING, number=1,) class BuildOccurrence(proto.Message): r"""Details of a build occurrence. Attributes: - provenance (~.g_provenance.BuildProvenance): + provenance (grafeas.grafeas_v1.types.BuildProvenance): Required. The actual provenance for the build. provenance_bytes (str): @@ -65,8 +62,7 @@ class BuildOccurrence(proto.Message): provenance = proto.Field( proto.MESSAGE, number=1, message=g_provenance.BuildProvenance, ) - - provenance_bytes = proto.Field(proto.STRING, number=2) + provenance_bytes = proto.Field(proto.STRING, number=2,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/grafeas/grafeas/grafeas_v1/types/common.py b/packages/grafeas/grafeas/grafeas_v1/types/common.py index 9731660dd6ad..74bb18c5e8c3 100644 --- a/packages/grafeas/grafeas/grafeas_v1/types/common.py +++ b/packages/grafeas/grafeas/grafeas_v1/types/common.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore @@ -46,9 +44,8 @@ class RelatedUrl(proto.Message): Label to describe usage of the URL. """ - url = proto.Field(proto.STRING, number=1) - - label = proto.Field(proto.STRING, number=2) + url = proto.Field(proto.STRING, number=1,) + label = proto.Field(proto.STRING, number=2,) class Signature(proto.Message): @@ -113,9 +110,8 @@ class Signature(proto.Message): - "nih:///sha-256;703f68f42aba2c6de30f488a5ea122fef76324679c9bf89791ba95a1271589a5". """ - signature = proto.Field(proto.BYTES, number=1) - - public_key_id = proto.Field(proto.STRING, number=2) + signature = proto.Field(proto.BYTES, number=1,) + public_key_id = proto.Field(proto.STRING, number=2,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/grafeas/grafeas/grafeas_v1/types/cvss.py b/packages/grafeas/grafeas/grafeas_v1/types/cvss.py index a466e9f9dbe0..98bd25d19917 100644 --- a/packages/grafeas/grafeas/grafeas_v1/types/cvss.py +++ b/packages/grafeas/grafeas/grafeas_v1/types/cvss.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore @@ -34,24 +32,24 @@ class CVSSv3(proto.Message): impact_score (float): - attack_vector (~.cvss.CVSSv3.AttackVector): + 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 (~.cvss.CVSSv3.AttackComplexity): + attack_complexity (grafeas.grafeas_v1.types.CVSSv3.AttackComplexity): - privileges_required (~.cvss.CVSSv3.PrivilegesRequired): + privileges_required (grafeas.grafeas_v1.types.CVSSv3.PrivilegesRequired): - user_interaction (~.cvss.CVSSv3.UserInteraction): + user_interaction (grafeas.grafeas_v1.types.CVSSv3.UserInteraction): - scope (~.cvss.CVSSv3.Scope): + scope (grafeas.grafeas_v1.types.CVSSv3.Scope): - confidentiality_impact (~.cvss.CVSSv3.Impact): + confidentiality_impact (grafeas.grafeas_v1.types.CVSSv3.Impact): - integrity_impact (~.cvss.CVSSv3.Impact): + integrity_impact (grafeas.grafeas_v1.types.CVSSv3.Impact): - availability_impact (~.cvss.CVSSv3.Impact): + availability_impact (grafeas.grafeas_v1.types.CVSSv3.Impact): """ @@ -95,26 +93,16 @@ class Impact(proto.Enum): IMPACT_LOW = 2 IMPACT_NONE = 3 - base_score = proto.Field(proto.FLOAT, number=1) - - exploitability_score = proto.Field(proto.FLOAT, number=2) - - impact_score = proto.Field(proto.FLOAT, number=3) - + base_score = proto.Field(proto.FLOAT, number=1,) + exploitability_score = proto.Field(proto.FLOAT, number=2,) + impact_score = proto.Field(proto.FLOAT, number=3,) attack_vector = proto.Field(proto.ENUM, number=5, enum=AttackVector,) - attack_complexity = proto.Field(proto.ENUM, number=6, enum=AttackComplexity,) - privileges_required = proto.Field(proto.ENUM, number=7, enum=PrivilegesRequired,) - user_interaction = proto.Field(proto.ENUM, number=8, enum=UserInteraction,) - scope = proto.Field(proto.ENUM, number=9, enum=Scope,) - confidentiality_impact = proto.Field(proto.ENUM, number=10, enum=Impact,) - integrity_impact = proto.Field(proto.ENUM, number=11, enum=Impact,) - availability_impact = proto.Field(proto.ENUM, number=12, enum=Impact,) diff --git a/packages/grafeas/grafeas/grafeas_v1/types/deployment.py b/packages/grafeas/grafeas/grafeas_v1/types/deployment.py index 8cce8399c69c..bc8e8b529760 100644 --- a/packages/grafeas/grafeas/grafeas_v1/types/deployment.py +++ b/packages/grafeas/grafeas/grafeas_v1/types/deployment.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,11 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - -from google.protobuf import timestamp_pb2 as timestamp # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore __protobuf__ = proto.module( @@ -35,7 +32,7 @@ class DeploymentNote(proto.Message): deployed. """ - resource_uri = proto.RepeatedField(proto.STRING, number=1) + resource_uri = proto.RepeatedField(proto.STRING, number=1,) class DeploymentOccurrence(proto.Message): @@ -46,10 +43,10 @@ class DeploymentOccurrence(proto.Message): user_email (str): Identity of the user that triggered this deployment. - deploy_time (~.timestamp.Timestamp): + deploy_time (google.protobuf.timestamp_pb2.Timestamp): Required. Beginning of the lifetime of this deployment. - undeploy_time (~.timestamp.Timestamp): + undeploy_time (google.protobuf.timestamp_pb2.Timestamp): End of the lifetime of this deployment. config (str): Configuration used to create this deployment. @@ -60,7 +57,7 @@ class DeploymentOccurrence(proto.Message): Output only. Resource URI for the artifact being deployed taken from the deployable field with the same name. - platform (~.deployment.DeploymentOccurrence.Platform): + platform (grafeas.grafeas_v1.types.DeploymentOccurrence.Platform): Platform hosting this deployment. """ @@ -71,18 +68,14 @@ class Platform(proto.Enum): FLEX = 2 CUSTOM = 3 - user_email = proto.Field(proto.STRING, number=1) - - deploy_time = proto.Field(proto.MESSAGE, number=2, message=timestamp.Timestamp,) - - undeploy_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) - - config = proto.Field(proto.STRING, number=4) - - address = proto.Field(proto.STRING, number=5) - - resource_uri = proto.RepeatedField(proto.STRING, number=6) - + user_email = proto.Field(proto.STRING, number=1,) + deploy_time = proto.Field(proto.MESSAGE, number=2, message=timestamp_pb2.Timestamp,) + undeploy_time = proto.Field( + proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp, + ) + config = proto.Field(proto.STRING, number=4,) + address = proto.Field(proto.STRING, number=5,) + resource_uri = proto.RepeatedField(proto.STRING, number=6,) platform = proto.Field(proto.ENUM, number=7, enum=Platform,) diff --git a/packages/grafeas/grafeas/grafeas_v1/types/discovery.py b/packages/grafeas/grafeas/grafeas_v1/types/discovery.py index 765cc07ed20f..85fa9fa95302 100644 --- a/packages/grafeas/grafeas/grafeas_v1/types/discovery.py +++ b/packages/grafeas/grafeas/grafeas_v1/types/discovery.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,12 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.rpc import status_pb2 as status # 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 @@ -34,7 +31,7 @@ class DiscoveryNote(proto.Message): is created in a consumer's project at the start of analysis. Attributes: - analysis_kind (~.common.NoteKind): + analysis_kind (grafeas.grafeas_v1.types.NoteKind): Required. Immutable. The kind of analysis that is handled by this discovery. """ @@ -47,19 +44,19 @@ class DiscoveryOccurrence(proto.Message): discovered resource. Attributes: - continuous_analysis (~.discovery.DiscoveryOccurrence.ContinuousAnalysis): + continuous_analysis (grafeas.grafeas_v1.types.DiscoveryOccurrence.ContinuousAnalysis): Whether the resource is continuously analyzed. - analysis_status (~.discovery.DiscoveryOccurrence.AnalysisStatus): + analysis_status (grafeas.grafeas_v1.types.DiscoveryOccurrence.AnalysisStatus): The status of discovery for the resource. - analysis_status_error (~.status.Status): + 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 (~.timestamp.Timestamp): + last_scan_time (google.protobuf.timestamp_pb2.Timestamp): The last time this resource was scanned. """ @@ -81,14 +78,14 @@ class AnalysisStatus(proto.Enum): FINISHED_UNSUPPORTED = 5 continuous_analysis = proto.Field(proto.ENUM, number=1, enum=ContinuousAnalysis,) - analysis_status = proto.Field(proto.ENUM, number=2, enum=AnalysisStatus,) - - analysis_status_error = proto.Field(proto.MESSAGE, number=3, message=status.Status,) - - cpe = proto.Field(proto.STRING, number=4) - - last_scan_time = proto.Field(proto.MESSAGE, number=5, message=timestamp.Timestamp,) + analysis_status_error = proto.Field( + proto.MESSAGE, number=3, message=status_pb2.Status, + ) + cpe = proto.Field(proto.STRING, number=4,) + last_scan_time = proto.Field( + proto.MESSAGE, number=5, message=timestamp_pb2.Timestamp, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/grafeas/grafeas/grafeas_v1/types/grafeas.py b/packages/grafeas/grafeas/grafeas_v1/types/grafeas.py index a3e37623a587..8dac5f2a616f 100644 --- a/packages/grafeas/grafeas/grafeas_v1/types/grafeas.py +++ b/packages/grafeas/grafeas/grafeas_v1/types/grafeas.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,12 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - -from google.protobuf import field_mask_pb2 as field_mask # type: ignore -from google.protobuf import timestamp_pb2 as timestamp # 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 @@ -77,95 +74,81 @@ class Occurrence(proto.Message): occurrence, in the form of ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. This field can be used as a filter in list requests. - kind (~.common.NoteKind): + 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 (~.timestamp.Timestamp): + create_time (google.protobuf.timestamp_pb2.Timestamp): Output only. The time this occurrence was created. - update_time (~.timestamp.Timestamp): + update_time (google.protobuf.timestamp_pb2.Timestamp): Output only. The time this occurrence was last updated. - vulnerability (~.g_vulnerability.VulnerabilityOccurrence): + vulnerability (grafeas.grafeas_v1.types.VulnerabilityOccurrence): Describes a security vulnerability. - build (~.g_build.BuildOccurrence): + build (grafeas.grafeas_v1.types.BuildOccurrence): Describes a verifiable build. - image (~.g_image.ImageOccurrence): + image (grafeas.grafeas_v1.types.ImageOccurrence): Describes how this resource derives from the basis in the associated note. - package (~.g_package.PackageOccurrence): + package (grafeas.grafeas_v1.types.PackageOccurrence): Describes the installation of a package on the linked resource. - deployment (~.g_deployment.DeploymentOccurrence): + deployment (grafeas.grafeas_v1.types.DeploymentOccurrence): Describes the deployment of an artifact on a runtime. - discovery (~.g_discovery.DiscoveryOccurrence): + discovery (grafeas.grafeas_v1.types.DiscoveryOccurrence): Describes when a resource was discovered. - attestation (~.g_attestation.AttestationOccurrence): + attestation (grafeas.grafeas_v1.types.AttestationOccurrence): Describes an attestation of an artifact. - upgrade (~.g_upgrade.UpgradeOccurrence): + upgrade (grafeas.grafeas_v1.types.UpgradeOccurrence): Describes an available package upgrade on the linked resource. """ - name = proto.Field(proto.STRING, number=1) - - resource_uri = proto.Field(proto.STRING, number=2) - - note_name = proto.Field(proto.STRING, number=3) - + name = proto.Field(proto.STRING, number=1,) + resource_uri = proto.Field(proto.STRING, number=2,) + note_name = proto.Field(proto.STRING, number=3,) kind = proto.Field(proto.ENUM, number=4, enum=common.NoteKind,) - - remediation = proto.Field(proto.STRING, number=5) - - create_time = proto.Field(proto.MESSAGE, number=6, message=timestamp.Timestamp,) - - update_time = proto.Field(proto.MESSAGE, number=7, message=timestamp.Timestamp,) - + remediation = proto.Field(proto.STRING, number=5,) + create_time = proto.Field(proto.MESSAGE, number=6, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=7, message=timestamp_pb2.Timestamp,) vulnerability = proto.Field( proto.MESSAGE, number=8, oneof="details", message=g_vulnerability.VulnerabilityOccurrence, ) - build = proto.Field( proto.MESSAGE, number=9, oneof="details", message=g_build.BuildOccurrence, ) - image = proto.Field( proto.MESSAGE, number=10, oneof="details", message=g_image.ImageOccurrence, ) - package = proto.Field( proto.MESSAGE, number=11, oneof="details", message=g_package.PackageOccurrence, ) - deployment = proto.Field( proto.MESSAGE, number=12, oneof="details", message=g_deployment.DeploymentOccurrence, ) - discovery = proto.Field( proto.MESSAGE, number=13, oneof="details", message=g_discovery.DiscoveryOccurrence, ) - attestation = proto.Field( proto.MESSAGE, number=14, oneof="details", message=g_attestation.AttestationOccurrence, ) - upgrade = proto.Field( proto.MESSAGE, number=15, oneof="details", message=g_upgrade.UpgradeOccurrence, ) @@ -182,97 +165,83 @@ class Note(proto.Message): A one sentence description of this note. long_description (str): A detailed description of this note. - kind (~.common.NoteKind): + 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 (Sequence[~.common.RelatedUrl]): + related_url (Sequence[grafeas.grafeas_v1.types.RelatedUrl]): URLs associated with this note. - expiration_time (~.timestamp.Timestamp): + expiration_time (google.protobuf.timestamp_pb2.Timestamp): Time of expiration for this note. Empty if note does not expire. - create_time (~.timestamp.Timestamp): + 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 (~.timestamp.Timestamp): + 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 (Sequence[str]): Other notes related to this note. - vulnerability (~.g_vulnerability.VulnerabilityNote): + vulnerability (grafeas.grafeas_v1.types.VulnerabilityNote): A note describing a package vulnerability. - build (~.g_build.BuildNote): + build (grafeas.grafeas_v1.types.BuildNote): A note describing build provenance for a verifiable build. - image (~.g_image.ImageNote): + image (grafeas.grafeas_v1.types.ImageNote): A note describing a base image. - package (~.g_package.PackageNote): + package (grafeas.grafeas_v1.types.PackageNote): A note describing a package hosted by various package managers. - deployment (~.g_deployment.DeploymentNote): + deployment (grafeas.grafeas_v1.types.DeploymentNote): A note describing something that can be deployed. - discovery (~.g_discovery.DiscoveryNote): + discovery (grafeas.grafeas_v1.types.DiscoveryNote): A note describing the initial analysis of a resource. - attestation (~.g_attestation.AttestationNote): + attestation (grafeas.grafeas_v1.types.AttestationNote): A note describing an attestation role. - upgrade (~.g_upgrade.UpgradeNote): + upgrade (grafeas.grafeas_v1.types.UpgradeNote): A note describing available package upgrades. """ - name = proto.Field(proto.STRING, number=1) - - short_description = proto.Field(proto.STRING, number=2) - - long_description = proto.Field(proto.STRING, number=3) - + name = proto.Field(proto.STRING, number=1,) + short_description = proto.Field(proto.STRING, number=2,) + long_description = proto.Field(proto.STRING, number=3,) kind = proto.Field(proto.ENUM, number=4, enum=common.NoteKind,) - related_url = proto.RepeatedField( proto.MESSAGE, number=5, message=common.RelatedUrl, ) - - expiration_time = proto.Field(proto.MESSAGE, number=6, message=timestamp.Timestamp,) - - create_time = proto.Field(proto.MESSAGE, number=7, message=timestamp.Timestamp,) - - update_time = proto.Field(proto.MESSAGE, number=8, message=timestamp.Timestamp,) - - related_note_names = proto.RepeatedField(proto.STRING, number=9) - + expiration_time = proto.Field( + proto.MESSAGE, number=6, message=timestamp_pb2.Timestamp, + ) + create_time = proto.Field(proto.MESSAGE, number=7, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=8, message=timestamp_pb2.Timestamp,) + related_note_names = proto.RepeatedField(proto.STRING, number=9,) vulnerability = proto.Field( proto.MESSAGE, number=10, oneof="type", message=g_vulnerability.VulnerabilityNote, ) - build = proto.Field( proto.MESSAGE, number=11, oneof="type", message=g_build.BuildNote, ) - image = proto.Field( proto.MESSAGE, number=12, oneof="type", message=g_image.ImageNote, ) - package = proto.Field( proto.MESSAGE, number=13, oneof="type", message=g_package.PackageNote, ) - deployment = proto.Field( proto.MESSAGE, number=14, oneof="type", message=g_deployment.DeploymentNote, ) - discovery = proto.Field( proto.MESSAGE, number=15, oneof="type", message=g_discovery.DiscoveryNote, ) - attestation = proto.Field( proto.MESSAGE, number=16, oneof="type", message=g_attestation.AttestationNote, ) - upgrade = proto.Field( proto.MESSAGE, number=17, oneof="type", message=g_upgrade.UpgradeNote, ) @@ -287,7 +256,7 @@ class GetOccurrenceRequest(proto.Message): ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. """ - name = proto.Field(proto.STRING, number=1) + name = proto.Field(proto.STRING, number=1,) class ListOccurrencesRequest(proto.Message): @@ -308,20 +277,17 @@ class ListOccurrencesRequest(proto.Message): in the list. """ - parent = proto.Field(proto.STRING, number=1) - - filter = proto.Field(proto.STRING, number=2) - - page_size = proto.Field(proto.INT32, number=3) - - page_token = proto.Field(proto.STRING, number=4) + parent = proto.Field(proto.STRING, number=1,) + filter = proto.Field(proto.STRING, number=2,) + page_size = proto.Field(proto.INT32, number=3,) + page_token = proto.Field(proto.STRING, number=4,) class ListOccurrencesResponse(proto.Message): r"""Response for listing occurrences. Attributes: - occurrences (Sequence[~.grafeas.Occurrence]): + occurrences (Sequence[grafeas.grafeas_v1.types.Occurrence]): The occurrences requested. next_page_token (str): The next pagination token in the list response. It should be @@ -333,9 +299,8 @@ class ListOccurrencesResponse(proto.Message): def raw_page(self): return self - occurrences = proto.RepeatedField(proto.MESSAGE, number=1, message=Occurrence,) - - next_page_token = proto.Field(proto.STRING, number=2) + occurrences = proto.RepeatedField(proto.MESSAGE, number=1, message="Occurrence",) + next_page_token = proto.Field(proto.STRING, number=2,) class DeleteOccurrenceRequest(proto.Message): @@ -347,7 +312,7 @@ class DeleteOccurrenceRequest(proto.Message): ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. """ - name = proto.Field(proto.STRING, number=1) + name = proto.Field(proto.STRING, number=1,) class CreateOccurrenceRequest(proto.Message): @@ -358,13 +323,12 @@ class CreateOccurrenceRequest(proto.Message): The name of the project in the form of ``projects/[PROJECT_ID]``, under which the occurrence is to be created. - occurrence (~.grafeas.Occurrence): + occurrence (grafeas.grafeas_v1.types.Occurrence): The occurrence to create. """ - parent = proto.Field(proto.STRING, number=1) - - occurrence = proto.Field(proto.MESSAGE, number=2, message=Occurrence,) + parent = proto.Field(proto.STRING, number=1,) + occurrence = proto.Field(proto.MESSAGE, number=2, message="Occurrence",) class UpdateOccurrenceRequest(proto.Message): @@ -374,17 +338,17 @@ class UpdateOccurrenceRequest(proto.Message): name (str): The name of the occurrence in the form of ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. - occurrence (~.grafeas.Occurrence): + occurrence (grafeas.grafeas_v1.types.Occurrence): The updated occurrence. - update_mask (~.field_mask.FieldMask): + update_mask (google.protobuf.field_mask_pb2.FieldMask): The fields to update. """ - name = proto.Field(proto.STRING, number=1) - - occurrence = proto.Field(proto.MESSAGE, number=2, message=Occurrence,) - - update_mask = proto.Field(proto.MESSAGE, number=3, message=field_mask.FieldMask,) + name = proto.Field(proto.STRING, number=1,) + occurrence = proto.Field(proto.MESSAGE, number=2, message="Occurrence",) + update_mask = proto.Field( + proto.MESSAGE, number=3, message=field_mask_pb2.FieldMask, + ) class GetNoteRequest(proto.Message): @@ -396,7 +360,7 @@ class GetNoteRequest(proto.Message): ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. """ - name = proto.Field(proto.STRING, number=1) + name = proto.Field(proto.STRING, number=1,) class GetOccurrenceNoteRequest(proto.Message): @@ -409,7 +373,7 @@ class GetOccurrenceNoteRequest(proto.Message): ``projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]``. """ - name = proto.Field(proto.STRING, number=1) + name = proto.Field(proto.STRING, number=1,) class ListNotesRequest(proto.Message): @@ -430,20 +394,17 @@ class ListNotesRequest(proto.Message): in the list. """ - parent = proto.Field(proto.STRING, number=1) - - filter = proto.Field(proto.STRING, number=2) - - page_size = proto.Field(proto.INT32, number=3) - - page_token = proto.Field(proto.STRING, number=4) + parent = proto.Field(proto.STRING, number=1,) + filter = proto.Field(proto.STRING, number=2,) + page_size = proto.Field(proto.INT32, number=3,) + page_token = proto.Field(proto.STRING, number=4,) class ListNotesResponse(proto.Message): r"""Response for listing notes. Attributes: - notes (Sequence[~.grafeas.Note]): + notes (Sequence[grafeas.grafeas_v1.types.Note]): The notes requested. next_page_token (str): The next pagination token in the list response. It should be @@ -455,9 +416,8 @@ class ListNotesResponse(proto.Message): def raw_page(self): return self - notes = proto.RepeatedField(proto.MESSAGE, number=1, message=Note,) - - next_page_token = proto.Field(proto.STRING, number=2) + notes = proto.RepeatedField(proto.MESSAGE, number=1, message="Note",) + next_page_token = proto.Field(proto.STRING, number=2,) class DeleteNoteRequest(proto.Message): @@ -469,7 +429,7 @@ class DeleteNoteRequest(proto.Message): ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. """ - name = proto.Field(proto.STRING, number=1) + name = proto.Field(proto.STRING, number=1,) class CreateNoteRequest(proto.Message): @@ -482,15 +442,13 @@ class CreateNoteRequest(proto.Message): created. note_id (str): The ID to use for this note. - note (~.grafeas.Note): + note (grafeas.grafeas_v1.types.Note): The note to create. """ - parent = proto.Field(proto.STRING, number=1) - - note_id = proto.Field(proto.STRING, number=2) - - note = proto.Field(proto.MESSAGE, number=3, message=Note,) + parent = proto.Field(proto.STRING, number=1,) + note_id = proto.Field(proto.STRING, number=2,) + note = proto.Field(proto.MESSAGE, number=3, message="Note",) class UpdateNoteRequest(proto.Message): @@ -500,17 +458,17 @@ class UpdateNoteRequest(proto.Message): name (str): The name of the note in the form of ``projects/[PROVIDER_ID]/notes/[NOTE_ID]``. - note (~.grafeas.Note): + note (grafeas.grafeas_v1.types.Note): The updated note. - update_mask (~.field_mask.FieldMask): + update_mask (google.protobuf.field_mask_pb2.FieldMask): The fields to update. """ - name = proto.Field(proto.STRING, number=1) - - note = proto.Field(proto.MESSAGE, number=2, message=Note,) - - update_mask = proto.Field(proto.MESSAGE, number=3, message=field_mask.FieldMask,) + name = proto.Field(proto.STRING, number=1,) + note = proto.Field(proto.MESSAGE, number=2, message="Note",) + update_mask = proto.Field( + proto.MESSAGE, number=3, message=field_mask_pb2.FieldMask, + ) class ListNoteOccurrencesRequest(proto.Message): @@ -529,20 +487,17 @@ class ListNoteOccurrencesRequest(proto.Message): in the list. """ - name = proto.Field(proto.STRING, number=1) - - filter = proto.Field(proto.STRING, number=2) - - page_size = proto.Field(proto.INT32, number=3) - - page_token = proto.Field(proto.STRING, number=4) + name = proto.Field(proto.STRING, number=1,) + filter = proto.Field(proto.STRING, number=2,) + page_size = proto.Field(proto.INT32, number=3,) + page_token = proto.Field(proto.STRING, number=4,) class ListNoteOccurrencesResponse(proto.Message): r"""Response for listing occurrences for a note. Attributes: - occurrences (Sequence[~.grafeas.Occurrence]): + occurrences (Sequence[grafeas.grafeas_v1.types.Occurrence]): The occurrences attached to the specified note. next_page_token (str): @@ -554,9 +509,8 @@ class ListNoteOccurrencesResponse(proto.Message): def raw_page(self): return self - occurrences = proto.RepeatedField(proto.MESSAGE, number=1, message=Occurrence,) - - next_page_token = proto.Field(proto.STRING, number=2) + occurrences = proto.RepeatedField(proto.MESSAGE, number=1, message="Occurrence",) + next_page_token = proto.Field(proto.STRING, number=2,) class BatchCreateNotesRequest(proto.Message): @@ -567,25 +521,24 @@ class BatchCreateNotesRequest(proto.Message): The name of the project in the form of ``projects/[PROJECT_ID]``, under which the notes are to be created. - notes (Sequence[~.grafeas.BatchCreateNotesRequest.NotesEntry]): + notes (Sequence[grafeas.grafeas_v1.types.BatchCreateNotesRequest.NotesEntry]): The notes to create. Max allowed length is 1000. """ - parent = proto.Field(proto.STRING, number=1) - - notes = proto.MapField(proto.STRING, proto.MESSAGE, number=2, message=Note,) + parent = proto.Field(proto.STRING, number=1,) + notes = proto.MapField(proto.STRING, proto.MESSAGE, number=2, message="Note",) class BatchCreateNotesResponse(proto.Message): r"""Response for creating notes in batch. Attributes: - notes (Sequence[~.grafeas.Note]): + notes (Sequence[grafeas.grafeas_v1.types.Note]): The notes that were created. """ - notes = proto.RepeatedField(proto.MESSAGE, number=1, message=Note,) + notes = proto.RepeatedField(proto.MESSAGE, number=1, message="Note",) class BatchCreateOccurrencesRequest(proto.Message): @@ -596,25 +549,24 @@ class BatchCreateOccurrencesRequest(proto.Message): The name of the project in the form of ``projects/[PROJECT_ID]``, under which the occurrences are to be created. - occurrences (Sequence[~.grafeas.Occurrence]): + occurrences (Sequence[grafeas.grafeas_v1.types.Occurrence]): The occurrences to create. Max allowed length is 1000. """ - parent = proto.Field(proto.STRING, number=1) - - occurrences = proto.RepeatedField(proto.MESSAGE, number=2, message=Occurrence,) + parent = proto.Field(proto.STRING, number=1,) + occurrences = proto.RepeatedField(proto.MESSAGE, number=2, message="Occurrence",) class BatchCreateOccurrencesResponse(proto.Message): r"""Response for creating occurrences in batch. Attributes: - occurrences (Sequence[~.grafeas.Occurrence]): + occurrences (Sequence[grafeas.grafeas_v1.types.Occurrence]): The occurrences that were created. """ - occurrences = proto.RepeatedField(proto.MESSAGE, number=1, message=Occurrence,) + occurrences = proto.RepeatedField(proto.MESSAGE, number=1, message="Occurrence",) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/grafeas/grafeas/grafeas_v1/types/image.py b/packages/grafeas/grafeas/grafeas_v1/types/image.py index 07ab7da77dc2..281c4444c4a1 100644 --- a/packages/grafeas/grafeas/grafeas_v1/types/image.py +++ b/packages/grafeas/grafeas/grafeas_v1/types/image.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore @@ -38,9 +36,8 @@ class Layer(proto.Message): directive. """ - directive = proto.Field(proto.STRING, number=1) - - arguments = proto.Field(proto.STRING, number=2) + directive = proto.Field(proto.STRING, number=1,) + arguments = proto.Field(proto.STRING, number=2,) class Fingerprint(proto.Message): @@ -60,11 +57,9 @@ class Fingerprint(proto.Message): v2_name[N+1]) Only the name of the final blob is kept. """ - v1_name = proto.Field(proto.STRING, number=1) - - v2_blob = proto.RepeatedField(proto.STRING, number=2) - - v2_name = proto.Field(proto.STRING, number=3) + v1_name = proto.Field(proto.STRING, number=1,) + v2_blob = proto.RepeatedField(proto.STRING, number=2,) + v2_name = proto.Field(proto.STRING, number=3,) class ImageNote(proto.Message): @@ -77,14 +72,13 @@ class ImageNote(proto.Message): resource_url (str): Required. Immutable. The resource_url for the resource representing the basis of associated occurrence images. - fingerprint (~.image.Fingerprint): + fingerprint (grafeas.grafeas_v1.types.Fingerprint): Required. Immutable. The fingerprint of the base image. """ - resource_url = proto.Field(proto.STRING, number=1) - - fingerprint = proto.Field(proto.MESSAGE, number=2, message=Fingerprint,) + resource_url = proto.Field(proto.STRING, number=1,) + fingerprint = proto.Field(proto.MESSAGE, number=2, message="Fingerprint",) class ImageOccurrence(proto.Message): @@ -93,14 +87,14 @@ class ImageOccurrence(proto.Message): with FROM . Attributes: - fingerprint (~.image.Fingerprint): + 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 (Sequence[~.image.Layer]): + layer_info (Sequence[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 @@ -110,13 +104,10 @@ class ImageOccurrence(proto.Message): for the derived image occurrence. """ - fingerprint = proto.Field(proto.MESSAGE, number=1, message=Fingerprint,) - - distance = proto.Field(proto.INT32, number=2) - - layer_info = proto.RepeatedField(proto.MESSAGE, number=3, message=Layer,) - - base_resource_url = proto.Field(proto.STRING, number=4) + fingerprint = proto.Field(proto.MESSAGE, number=1, message="Fingerprint",) + distance = proto.Field(proto.INT32, number=2,) + layer_info = proto.RepeatedField(proto.MESSAGE, number=3, message="Layer",) + base_resource_url = proto.Field(proto.STRING, number=4,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/grafeas/grafeas/grafeas_v1/types/package.py b/packages/grafeas/grafeas/grafeas_v1/types/package.py index 348872445667..45b1bf9e569a 100644 --- a/packages/grafeas/grafeas/grafeas_v1/types/package.py +++ b/packages/grafeas/grafeas/grafeas_v1/types/package.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore @@ -49,10 +47,10 @@ class Distribution(proto.Message): Required. The cpe_uri in `CPE format `__ denoting the package manager version distributing a package. - architecture (~.package.Architecture): + architecture (grafeas.grafeas_v1.types.Architecture): The CPU architecture for which packages in this distribution channel were built. - latest_version (~.package.Version): + latest_version (grafeas.grafeas_v1.types.Version): The latest available version of this package in this distribution channel. maintainer (str): @@ -66,17 +64,12 @@ class Distribution(proto.Message): of this package. """ - cpe_uri = proto.Field(proto.STRING, number=1) - + cpe_uri = proto.Field(proto.STRING, number=1,) architecture = proto.Field(proto.ENUM, number=2, enum="Architecture",) - latest_version = proto.Field(proto.MESSAGE, number=3, message="Version",) - - maintainer = proto.Field(proto.STRING, number=4) - - url = proto.Field(proto.STRING, number=5) - - description = proto.Field(proto.STRING, number=6) + maintainer = proto.Field(proto.STRING, number=4,) + url = proto.Field(proto.STRING, number=5,) + description = proto.Field(proto.STRING, number=6,) class Location(proto.Message): @@ -89,18 +82,16 @@ class Location(proto.Message): Required. The CPE URI in `CPE format `__ denoting the package manager version distributing a package. - version (~.package.Version): + version (grafeas.grafeas_v1.types.Version): The version installed at this location. path (str): The path from which we gathered that this package/version is installed. """ - cpe_uri = proto.Field(proto.STRING, number=1) - + cpe_uri = proto.Field(proto.STRING, number=1,) version = proto.Field(proto.MESSAGE, number=2, message="Version",) - - path = proto.Field(proto.STRING, number=3) + path = proto.Field(proto.STRING, number=3,) class PackageNote(proto.Message): @@ -111,14 +102,15 @@ class PackageNote(proto.Message): Attributes: name (str): Required. Immutable. The name of the package. - distribution (Sequence[~.package.Distribution]): + distribution (Sequence[grafeas.grafeas_v1.types.Distribution]): The various channels by which a package is distributed. """ - name = proto.Field(proto.STRING, number=1) - - distribution = proto.RepeatedField(proto.MESSAGE, number=10, message=Distribution,) + name = proto.Field(proto.STRING, number=1,) + distribution = proto.RepeatedField( + proto.MESSAGE, number=10, message="Distribution", + ) class PackageOccurrence(proto.Message): @@ -129,15 +121,14 @@ class PackageOccurrence(proto.Message): name (str): Output only. The name of the installed package. - location (Sequence[~.package.Location]): + location (Sequence[grafeas.grafeas_v1.types.Location]): Required. All of the places within the filesystem versions of this package have been found. """ - name = proto.Field(proto.STRING, number=1) - - location = proto.RepeatedField(proto.MESSAGE, number=2, message=Location,) + name = proto.Field(proto.STRING, number=1,) + location = proto.RepeatedField(proto.MESSAGE, number=2, message="Location",) class Version(proto.Message): @@ -154,7 +145,7 @@ class Version(proto.Message): revision (str): The iteration of the package build from the above version. - kind (~.package.Version.VersionKind): + kind (grafeas.grafeas_v1.types.Version.VersionKind): Required. Distinguishes between sentinel MIN/MAX versions and normal versions. full_name (str): @@ -172,15 +163,11 @@ class VersionKind(proto.Enum): MINIMUM = 2 MAXIMUM = 3 - epoch = proto.Field(proto.INT32, number=1) - - name = proto.Field(proto.STRING, number=2) - - revision = proto.Field(proto.STRING, number=3) - + epoch = proto.Field(proto.INT32, number=1,) + name = proto.Field(proto.STRING, number=2,) + revision = proto.Field(proto.STRING, number=3,) kind = proto.Field(proto.ENUM, number=4, enum=VersionKind,) - - full_name = proto.Field(proto.STRING, number=5) + full_name = proto.Field(proto.STRING, number=5,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/grafeas/grafeas/grafeas_v1/types/provenance.py b/packages/grafeas/grafeas/grafeas_v1/types/provenance.py index 53079d1943af..e4e748b252e6 100644 --- a/packages/grafeas/grafeas/grafeas_v1/types/provenance.py +++ b/packages/grafeas/grafeas/grafeas_v1/types/provenance.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,11 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - -from google.protobuf import timestamp_pb2 as timestamp # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore __protobuf__ = proto.module( @@ -51,16 +48,16 @@ class BuildProvenance(proto.Message): Required. Unique identifier of the build. project_id (str): ID of the project. - commands (Sequence[~.provenance.Command]): + commands (Sequence[grafeas.grafeas_v1.types.Command]): Commands requested by the build. - built_artifacts (Sequence[~.provenance.Artifact]): + built_artifacts (Sequence[grafeas.grafeas_v1.types.Artifact]): Output of the build. - create_time (~.timestamp.Timestamp): + create_time (google.protobuf.timestamp_pb2.Timestamp): Time at which the build was created. - start_time (~.timestamp.Timestamp): + start_time (google.protobuf.timestamp_pb2.Timestamp): Time at which execution of the build was started. - end_time (~.timestamp.Timestamp): + end_time (google.protobuf.timestamp_pb2.Timestamp): Time at which execution of the build was finished. creator (str): @@ -72,12 +69,12 @@ class BuildProvenance(proto.Message): logs_uri (str): URI where any logs for this provenance were written. - source_provenance (~.provenance.Source): + 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 (Sequence[~.provenance.BuildProvenance.BuildOptionsEntry]): + build_options (Sequence[grafeas.grafeas_v1.types.BuildProvenance.BuildOptionsEntry]): Special options applied to this build. This is a catch-all field where build providers can enter any desired additional details. @@ -86,31 +83,19 @@ class BuildProvenance(proto.Message): this build was executed. """ - id = proto.Field(proto.STRING, number=1) - - project_id = proto.Field(proto.STRING, number=2) - + id = proto.Field(proto.STRING, number=1,) + project_id = proto.Field(proto.STRING, number=2,) commands = proto.RepeatedField(proto.MESSAGE, number=3, message="Command",) - built_artifacts = proto.RepeatedField(proto.MESSAGE, number=4, message="Artifact",) - - create_time = proto.Field(proto.MESSAGE, number=5, message=timestamp.Timestamp,) - - start_time = proto.Field(proto.MESSAGE, number=6, message=timestamp.Timestamp,) - - end_time = proto.Field(proto.MESSAGE, number=7, message=timestamp.Timestamp,) - - creator = proto.Field(proto.STRING, number=8) - - logs_uri = proto.Field(proto.STRING, number=9) - + create_time = proto.Field(proto.MESSAGE, number=5, message=timestamp_pb2.Timestamp,) + start_time = proto.Field(proto.MESSAGE, number=6, message=timestamp_pb2.Timestamp,) + end_time = proto.Field(proto.MESSAGE, number=7, message=timestamp_pb2.Timestamp,) + creator = proto.Field(proto.STRING, number=8,) + logs_uri = proto.Field(proto.STRING, number=9,) source_provenance = proto.Field(proto.MESSAGE, number=10, message="Source",) - - trigger_id = proto.Field(proto.STRING, number=11) - - build_options = proto.MapField(proto.STRING, proto.STRING, number=12) - - builder_version = proto.Field(proto.STRING, number=13) + trigger_id = proto.Field(proto.STRING, number=11,) + build_options = proto.MapField(proto.STRING, proto.STRING, number=12,) + builder_version = proto.Field(proto.STRING, number=13,) class Source(proto.Message): @@ -121,7 +106,7 @@ class Source(proto.Message): artifact_storage_source_uri (str): If provided, the input binary artifacts for the build came from this location. - file_hashes (Sequence[~.provenance.Source.FileHashesEntry]): + file_hashes (Sequence[grafeas.grafeas_v1.types.Source.FileHashesEntry]): Hash(es) of the build source, which can be used to verify that the original source integrity was maintained in the build. @@ -133,10 +118,10 @@ class Source(proto.Message): such as a gzipped tarfile (.tar.gz), the FileHash will be for the single path to that file. - context (~.provenance.SourceContext): + context (grafeas.grafeas_v1.types.SourceContext): If provided, the source code used for the build came from this location. - additional_contexts (Sequence[~.provenance.SourceContext]): + additional_contexts (Sequence[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 @@ -145,14 +130,11 @@ class Source(proto.Message): field. """ - artifact_storage_source_uri = proto.Field(proto.STRING, number=1) - + artifact_storage_source_uri = proto.Field(proto.STRING, number=1,) file_hashes = proto.MapField( proto.STRING, proto.MESSAGE, number=2, message="FileHashes", ) - context = proto.Field(proto.MESSAGE, number=3, message="SourceContext",) - additional_contexts = proto.RepeatedField( proto.MESSAGE, number=4, message="SourceContext", ) @@ -164,7 +146,7 @@ class FileHashes(proto.Message): build. Attributes: - file_hash (Sequence[~.provenance.Hash]): + file_hash (Sequence[grafeas.grafeas_v1.types.Hash]): Required. Collection of file hashes. """ @@ -175,16 +157,15 @@ class Hash(proto.Message): r"""Container message for hash values. Attributes: - type (str): + type_ (str): Required. The type of hash that was performed, e.g. "SHA-256". value (bytes): Required. The hash value. """ - type = proto.Field(proto.STRING, number=1) - - value = proto.Field(proto.BYTES, number=2) + type_ = proto.Field(proto.STRING, number=1,) + value = proto.Field(proto.BYTES, number=2,) class Command(proto.Message): @@ -202,7 +183,7 @@ class Command(proto.Message): args (Sequence[str]): Command-line arguments used when executing this command. - dir (str): + dir_ (str): Working directory (relative to project source root) used when running this command. id (str): @@ -213,17 +194,12 @@ class Command(proto.Message): depends on. """ - name = proto.Field(proto.STRING, number=1) - - env = proto.RepeatedField(proto.STRING, number=2) - - args = proto.RepeatedField(proto.STRING, number=3) - - dir = proto.Field(proto.STRING, number=4) - - id = proto.Field(proto.STRING, number=5) - - wait_for = proto.RepeatedField(proto.STRING, number=6) + name = proto.Field(proto.STRING, number=1,) + env = proto.RepeatedField(proto.STRING, number=2,) + args = proto.RepeatedField(proto.STRING, number=3,) + dir_ = proto.Field(proto.STRING, number=4,) + id = proto.Field(proto.STRING, number=5,) + wait_for = proto.RepeatedField(proto.STRING, number=6,) class Artifact(proto.Message): @@ -246,11 +222,9 @@ class Artifact(proto.Message): to one image. """ - checksum = proto.Field(proto.STRING, number=1) - - id = proto.Field(proto.STRING, number=2) - - names = proto.RepeatedField(proto.STRING, number=3) + checksum = proto.Field(proto.STRING, number=1,) + id = proto.Field(proto.STRING, number=2,) + names = proto.RepeatedField(proto.STRING, number=3,) class SourceContext(proto.Message): @@ -259,39 +233,36 @@ class SourceContext(proto.Message): a single file or directory. Attributes: - cloud_repo (~.provenance.CloudRepoSourceContext): + cloud_repo (grafeas.grafeas_v1.types.CloudRepoSourceContext): A SourceContext referring to a revision in a Google Cloud Source Repo. - gerrit (~.provenance.GerritSourceContext): + gerrit (grafeas.grafeas_v1.types.GerritSourceContext): A SourceContext referring to a Gerrit project. - git (~.provenance.GitSourceContext): + git (grafeas.grafeas_v1.types.GitSourceContext): A SourceContext referring to any third party Git repo (e.g., GitHub). - labels (Sequence[~.provenance.SourceContext.LabelsEntry]): + labels (Sequence[grafeas.grafeas_v1.types.SourceContext.LabelsEntry]): Labels with user defined metadata. """ cloud_repo = proto.Field( proto.MESSAGE, number=1, oneof="context", message="CloudRepoSourceContext", ) - gerrit = proto.Field( proto.MESSAGE, number=2, oneof="context", message="GerritSourceContext", ) - git = proto.Field( proto.MESSAGE, number=3, oneof="context", message="GitSourceContext", ) - - labels = proto.MapField(proto.STRING, proto.STRING, number=4) + labels = proto.MapField(proto.STRING, proto.STRING, number=4,) class AliasContext(proto.Message): r"""An alias to a repo revision. Attributes: - kind (~.provenance.AliasContext.Kind): + kind (grafeas.grafeas_v1.types.AliasContext.Kind): The alias kind. name (str): The alias name. @@ -305,8 +276,7 @@ class Kind(proto.Enum): OTHER = 4 kind = proto.Field(proto.ENUM, number=1, enum=Kind,) - - name = proto.Field(proto.STRING, number=2) + name = proto.Field(proto.STRING, number=2,) class CloudRepoSourceContext(proto.Message): @@ -314,20 +284,18 @@ class CloudRepoSourceContext(proto.Message): Google Cloud Source Repo. Attributes: - repo_id (~.provenance.RepoId): + repo_id (grafeas.grafeas_v1.types.RepoId): The ID of the repo. revision_id (str): A revision ID. - alias_context (~.provenance.AliasContext): + alias_context (grafeas.grafeas_v1.types.AliasContext): An alias, which may be a branch or tag. """ repo_id = proto.Field(proto.MESSAGE, number=1, message="RepoId",) - - revision_id = proto.Field(proto.STRING, number=2, oneof="revision") - + revision_id = proto.Field(proto.STRING, number=2, oneof="revision",) alias_context = proto.Field( - proto.MESSAGE, number=3, oneof="revision", message=AliasContext, + proto.MESSAGE, number=3, oneof="revision", message="AliasContext", ) @@ -344,18 +312,15 @@ class GerritSourceContext(proto.Message): hostURI/project. revision_id (str): A revision (commit) ID. - alias_context (~.provenance.AliasContext): + alias_context (grafeas.grafeas_v1.types.AliasContext): An alias, which may be a branch or tag. """ - host_uri = proto.Field(proto.STRING, number=1) - - gerrit_project = proto.Field(proto.STRING, number=2) - - revision_id = proto.Field(proto.STRING, number=3, oneof="revision") - + host_uri = proto.Field(proto.STRING, number=1,) + gerrit_project = proto.Field(proto.STRING, number=2,) + revision_id = proto.Field(proto.STRING, number=3, oneof="revision",) alias_context = proto.Field( - proto.MESSAGE, number=4, oneof="revision", message=AliasContext, + proto.MESSAGE, number=4, oneof="revision", message="AliasContext", ) @@ -370,16 +335,15 @@ class GitSourceContext(proto.Message): Git commit hash. """ - url = proto.Field(proto.STRING, number=1) - - revision_id = proto.Field(proto.STRING, number=2) + url = proto.Field(proto.STRING, number=1,) + revision_id = proto.Field(proto.STRING, number=2,) class RepoId(proto.Message): r"""A unique identifier for a Cloud Repo. Attributes: - project_repo_id (~.provenance.ProjectRepoId): + project_repo_id (grafeas.grafeas_v1.types.ProjectRepoId): A combination of a project ID and a repo name. uid (str): @@ -390,8 +354,7 @@ class RepoId(proto.Message): project_repo_id = proto.Field( proto.MESSAGE, number=1, oneof="id", message="ProjectRepoId", ) - - uid = proto.Field(proto.STRING, number=2, oneof="id") + uid = proto.Field(proto.STRING, number=2, oneof="id",) class ProjectRepoId(proto.Message): @@ -406,9 +369,8 @@ class ProjectRepoId(proto.Message): default repo. """ - project_id = proto.Field(proto.STRING, number=1) - - repo_name = proto.Field(proto.STRING, number=2) + project_id = proto.Field(proto.STRING, number=1,) + repo_name = proto.Field(proto.STRING, number=2,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/grafeas/grafeas/grafeas_v1/types/upgrade.py b/packages/grafeas/grafeas/grafeas_v1/types/upgrade.py index 0f3308d57d0e..a6152fcde610 100644 --- a/packages/grafeas/grafeas/grafeas_v1/types/upgrade.py +++ b/packages/grafeas/grafeas/grafeas_v1/types/upgrade.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,11 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - -from google.protobuf import timestamp_pb2 as timestamp # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore from grafeas.grafeas_v1.types import package as g_package @@ -44,25 +41,22 @@ class UpgradeNote(proto.Message): package (str): Required for non-Windows OS. The package this Upgrade is for. - version (~.g_package.Version): + version (grafeas.grafeas_v1.types.Version): Required for non-Windows OS. The version of the package in machine + human readable form. - distributions (Sequence[~.upgrade.UpgradeDistribution]): + distributions (Sequence[grafeas.grafeas_v1.types.UpgradeDistribution]): Metadata about the upgrade for each specific operating system. - windows_update (~.upgrade.WindowsUpdate): + windows_update (grafeas.grafeas_v1.types.WindowsUpdate): Required for Windows OS. Represents the metadata about the Windows update. """ - package = proto.Field(proto.STRING, number=1) - + package = proto.Field(proto.STRING, number=1,) version = proto.Field(proto.MESSAGE, number=2, message=g_package.Version,) - distributions = proto.RepeatedField( proto.MESSAGE, number=3, message="UpgradeDistribution", ) - windows_update = proto.Field(proto.MESSAGE, number=4, message="WindowsUpdate",) @@ -90,13 +84,10 @@ class UpgradeDistribution(proto.Message): The cve tied to this Upgrade. """ - cpe_uri = proto.Field(proto.STRING, number=1) - - classification = proto.Field(proto.STRING, number=2) - - severity = proto.Field(proto.STRING, number=3) - - cve = proto.RepeatedField(proto.STRING, number=4) + cpe_uri = proto.Field(proto.STRING, number=1,) + classification = proto.Field(proto.STRING, number=2,) + severity = proto.Field(proto.STRING, number=3,) + cve = proto.RepeatedField(proto.STRING, number=4,) class WindowsUpdate(proto.Message): @@ -107,14 +98,14 @@ class WindowsUpdate(proto.Message): wuapi-iupdate. Attributes: - identity (~.upgrade.WindowsUpdate.Identity): + 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 (Sequence[~.upgrade.WindowsUpdate.Category]): + categories (Sequence[grafeas.grafeas_v1.types.WindowsUpdate.Category]): The list of categories to which the update belongs. kb_article_ids (Sequence[str]): @@ -123,13 +114,12 @@ class WindowsUpdate(proto.Message): support_url (str): The hyperlink to the support information for the update. - last_published_timestamp (~.timestamp.Timestamp): + 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 @@ -138,13 +128,11 @@ class Identity(proto.Message): The revision number of the update. """ - update_id = proto.Field(proto.STRING, number=1) - - revision = proto.Field(proto.INT32, number=2) + update_id = proto.Field(proto.STRING, number=1,) + revision = 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. @@ -152,24 +140,17 @@ class Category(proto.Message): The localized name of the category. """ - category_id = proto.Field(proto.STRING, number=1) - - name = proto.Field(proto.STRING, number=2) + category_id = proto.Field(proto.STRING, number=1,) + name = proto.Field(proto.STRING, number=2,) identity = proto.Field(proto.MESSAGE, number=1, message=Identity,) - - title = proto.Field(proto.STRING, number=2) - - description = proto.Field(proto.STRING, number=3) - + title = proto.Field(proto.STRING, number=2,) + description = proto.Field(proto.STRING, number=3,) categories = proto.RepeatedField(proto.MESSAGE, number=4, message=Category,) - - kb_article_ids = proto.RepeatedField(proto.STRING, number=5) - - support_url = proto.Field(proto.STRING, number=6) - + kb_article_ids = proto.RepeatedField(proto.STRING, number=5,) + support_url = proto.Field(proto.STRING, number=6,) last_published_timestamp = proto.Field( - proto.MESSAGE, number=7, message=timestamp.Timestamp, + proto.MESSAGE, number=7, message=timestamp_pb2.Timestamp, ) @@ -184,26 +165,23 @@ class UpgradeOccurrence(proto.Message): package (str): Required for non-Windows OS. The package this Upgrade is for. - parsed_version (~.g_package.Version): + parsed_version (grafeas.grafeas_v1.types.Version): Required for non-Windows OS. The version of the package in a machine + human readable form. - distribution (~.upgrade.UpgradeDistribution): + 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 (~.upgrade.WindowsUpdate): + windows_update (grafeas.grafeas_v1.types.WindowsUpdate): Required for Windows OS. Represents the metadata about the Windows update. """ - package = proto.Field(proto.STRING, number=1) - + package = proto.Field(proto.STRING, number=1,) parsed_version = proto.Field(proto.MESSAGE, number=3, message=g_package.Version,) - - distribution = proto.Field(proto.MESSAGE, number=4, message=UpgradeDistribution,) - - windows_update = proto.Field(proto.MESSAGE, number=5, message=WindowsUpdate,) + distribution = proto.Field(proto.MESSAGE, number=4, message="UpgradeDistribution",) + windows_update = proto.Field(proto.MESSAGE, number=5, message="WindowsUpdate",) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/grafeas/grafeas/grafeas_v1/types/vulnerability.py b/packages/grafeas/grafeas/grafeas_v1/types/vulnerability.py index 12626ab039cc..de5d63622cb2 100644 --- a/packages/grafeas/grafeas/grafeas_v1/types/vulnerability.py +++ b/packages/grafeas/grafeas/grafeas_v1/types/vulnerability.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,11 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - -from google.protobuf import timestamp_pb2 as timestamp # 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 @@ -48,23 +45,23 @@ class VulnerabilityNote(proto.Message): 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 (~.vulnerability.Severity): + severity (grafeas.grafeas_v1.types.Severity): The note provider assigned severity of this vulnerability. - details (Sequence[~.vulnerability.VulnerabilityNote.Detail]): + details (Sequence[grafeas.grafeas_v1.types.VulnerabilityNote.Detail]): Details of all known distros and packages affected by this vulnerability. - cvss_v3 (~.cvss.CVSSv3): + cvss_v3 (grafeas.grafeas_v1.types.CVSSv3): The full description of the CVSSv3 for this vulnerability. - windows_details (Sequence[~.vulnerability.VulnerabilityNote.WindowsDetail]): + windows_details (Sequence[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 (~.timestamp.Timestamp): + 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 @@ -93,7 +90,7 @@ class Detail(proto.Message): affected_package (str): Required. The package this vulnerability affects. - affected_version_start (~.package.Version): + 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 @@ -102,7 +99,7 @@ class Detail(proto.Message): 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 (~.package.Version): + 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 @@ -120,7 +117,7 @@ class Detail(proto.Message): 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 (~.package.Version): + 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 @@ -128,46 +125,34 @@ class Detail(proto.Message): is_obsolete (bool): Whether this detail is obsolete. Occurrences are expected not to point to obsolete details. - source_update_time (~.timestamp.Timestamp): + 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. """ - severity_name = proto.Field(proto.STRING, number=1) - - description = proto.Field(proto.STRING, number=2) - - package_type = proto.Field(proto.STRING, number=3) - - affected_cpe_uri = proto.Field(proto.STRING, number=4) - - affected_package = proto.Field(proto.STRING, number=5) - + severity_name = proto.Field(proto.STRING, number=1,) + description = proto.Field(proto.STRING, number=2,) + package_type = proto.Field(proto.STRING, number=3,) + affected_cpe_uri = proto.Field(proto.STRING, number=4,) + affected_package = proto.Field(proto.STRING, number=5,) affected_version_start = proto.Field( proto.MESSAGE, number=6, message=package.Version, ) - affected_version_end = proto.Field( proto.MESSAGE, number=7, message=package.Version, ) - - fixed_cpe_uri = proto.Field(proto.STRING, number=8) - - fixed_package = proto.Field(proto.STRING, number=9) - + fixed_cpe_uri = proto.Field(proto.STRING, number=8,) + fixed_package = proto.Field(proto.STRING, number=9,) fixed_version = proto.Field(proto.MESSAGE, number=10, message=package.Version,) - - is_obsolete = proto.Field(proto.BOOL, number=11) - + is_obsolete = proto.Field(proto.BOOL, number=11,) source_update_time = proto.Field( - proto.MESSAGE, number=12, message=timestamp.Timestamp, + proto.MESSAGE, number=12, message=timestamp_pb2.Timestamp, ) class WindowsDetail(proto.Message): r""" - Attributes: cpe_uri (str): Required. The `CPE @@ -177,7 +162,7 @@ class WindowsDetail(proto.Message): Required. The name of this vulnerability. description (str): The description of this vulnerability. - fixing_kbs (Sequence[~.vulnerability.VulnerabilityNote.WindowsDetail.KnowledgeBase]): + fixing_kbs (Sequence[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 @@ -188,7 +173,6 @@ class WindowsDetail(proto.Message): class KnowledgeBase(proto.Message): r""" - Attributes: name (str): The KB name (generally of the form KB[0-9]+ (e.g., @@ -198,36 +182,27 @@ class KnowledgeBase(proto.Message): (https://www.catalog.update.microsoft.com/). """ - name = proto.Field(proto.STRING, number=1) - - url = proto.Field(proto.STRING, number=2) - - cpe_uri = proto.Field(proto.STRING, number=1) - - name = proto.Field(proto.STRING, number=2) - - description = proto.Field(proto.STRING, number=3) + name = proto.Field(proto.STRING, number=1,) + url = proto.Field(proto.STRING, number=2,) + cpe_uri = proto.Field(proto.STRING, number=1,) + name = proto.Field(proto.STRING, number=2,) + description = proto.Field(proto.STRING, number=3,) fixing_kbs = proto.RepeatedField( proto.MESSAGE, number=4, message="VulnerabilityNote.WindowsDetail.KnowledgeBase", ) - cvss_score = proto.Field(proto.FLOAT, number=1) - + cvss_score = proto.Field(proto.FLOAT, number=1,) severity = proto.Field(proto.ENUM, number=2, enum="Severity",) - details = proto.RepeatedField(proto.MESSAGE, number=3, message=Detail,) - cvss_v3 = proto.Field(proto.MESSAGE, number=4, message=cvss.CVSSv3,) - windows_details = proto.RepeatedField( proto.MESSAGE, number=5, message=WindowsDetail, ) - source_update_time = proto.Field( - proto.MESSAGE, number=6, message=timestamp.Timestamp, + proto.MESSAGE, number=6, message=timestamp_pb2.Timestamp, ) @@ -235,11 +210,11 @@ class VulnerabilityOccurrence(proto.Message): r"""An occurrence of a severity vulnerability on a resource. Attributes: - type (str): + type_ (str): The type of package; whether native or non native (e.g., ruby gems, node.js packages, etc.). - severity (~.vulnerability.Severity): + severity (grafeas.grafeas_v1.types.Severity): Output only. The note provider assigned severity of this vulnerability. cvss_score (float): @@ -247,7 +222,7 @@ class VulnerabilityOccurrence(proto.Message): vulnerability. CVSS score is on a scale of 0 - 10 where 0 indicates low severity and 10 indicates high severity. - package_issue (Sequence[~.vulnerability.VulnerabilityOccurrence.PackageIssue]): + package_issue (Sequence[grafeas.grafeas_v1.types.VulnerabilityOccurrence.PackageIssue]): Required. The set of affected locations and their fixes (if available) within the associated resource. @@ -257,10 +232,10 @@ class VulnerabilityOccurrence(proto.Message): long_description (str): Output only. A detailed description of this vulnerability. - related_urls (Sequence[~.common.RelatedUrl]): + related_urls (Sequence[grafeas.grafeas_v1.types.RelatedUrl]): Output only. URLs related to this vulnerability. - effective_severity (~.vulnerability.Severity): + 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. @@ -282,7 +257,7 @@ class PackageIssue(proto.Message): affected_package (str): Required. The package this vulnerability was found in. - affected_version (~.package.Version): + affected_version (grafeas.grafeas_v1.types.Version): Required. The version of the package that is installed on the resource affected by this vulnerability. @@ -293,7 +268,7 @@ class PackageIssue(proto.Message): fixed_package (str): The package this vulnerability was fixed in. It is possible for this to be different from the affected_package. - fixed_version (~.package.Version): + 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 @@ -303,41 +278,27 @@ class PackageIssue(proto.Message): this package. """ - affected_cpe_uri = proto.Field(proto.STRING, number=1) - - affected_package = proto.Field(proto.STRING, number=2) - + affected_cpe_uri = proto.Field(proto.STRING, number=1,) + affected_package = proto.Field(proto.STRING, number=2,) affected_version = proto.Field( proto.MESSAGE, number=3, message=package.Version, ) - - fixed_cpe_uri = proto.Field(proto.STRING, number=4) - - fixed_package = proto.Field(proto.STRING, number=5) - + fixed_cpe_uri = proto.Field(proto.STRING, number=4,) + fixed_package = proto.Field(proto.STRING, number=5,) fixed_version = proto.Field(proto.MESSAGE, number=6, message=package.Version,) + fix_available = proto.Field(proto.BOOL, number=7,) - fix_available = proto.Field(proto.BOOL, number=7) - - type = proto.Field(proto.STRING, number=1) - + type_ = proto.Field(proto.STRING, number=1,) severity = proto.Field(proto.ENUM, number=2, enum="Severity",) - - cvss_score = proto.Field(proto.FLOAT, number=3) - + cvss_score = proto.Field(proto.FLOAT, number=3,) package_issue = proto.RepeatedField(proto.MESSAGE, number=4, message=PackageIssue,) - - short_description = proto.Field(proto.STRING, number=5) - - long_description = proto.Field(proto.STRING, number=6) - + short_description = proto.Field(proto.STRING, number=5,) + long_description = proto.Field(proto.STRING, number=6,) related_urls = proto.RepeatedField( proto.MESSAGE, number=7, message=common.RelatedUrl, ) - effective_severity = proto.Field(proto.ENUM, number=8, enum="Severity",) - - fix_available = proto.Field(proto.BOOL, number=9) + fix_available = proto.Field(proto.BOOL, number=9,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/grafeas/noxfile.py b/packages/grafeas/noxfile.py index e6d2ea41b30b..71930b359737 100644 --- a/packages/grafeas/noxfile.py +++ b/packages/grafeas/noxfile.py @@ -18,6 +18,7 @@ from __future__ import absolute_import import os +import pathlib import shutil import nox @@ -28,7 +29,23 @@ DEFAULT_PYTHON_VERSION = "3.8" SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"] -UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8"] +UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +# 'docfx' is excluded since it only needs to run in 'docs-presubmit' +nox.options.sessions = [ + "unit", + "system", + "cover", + "lint", + "lint_setup_py", + "blacken", + "docs", +] + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True @nox.session(python=DEFAULT_PYTHON_VERSION) @@ -45,16 +62,9 @@ def lint(session): session.run("flake8", "grafeas", "tests") -@nox.session(python="3.6") +@nox.session(python=DEFAULT_PYTHON_VERSION) def blacken(session): - """Run black. - - Format code to uniform standard. - - This currently uses Python 3.6 due to the automated Kokoro run of synthtool. - That run uses an image that doesn't have 3.6 installed. Before updating this - check the state of the `gcp_ubuntu_config` we use for that Kokoro run. - """ + """Run black. Format code to uniform standard.""" session.install(BLACK_VERSION) session.run( "black", *BLACK_PATHS, @@ -70,10 +80,15 @@ def lint_setup_py(session): def default(session): # Install all test dependencies, then install this package in-place. - session.install("asyncmock", "pytest-asyncio") - session.install("mock", "pytest", "pytest-cov") - session.install("-e", ".") + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + session.install("asyncmock", "pytest-asyncio", "-c", constraints_path) + + session.install("mock", "pytest", "pytest-cov", "-c", constraints_path) + + session.install("-e", ".", "-c", constraints_path) # Run py.test against the unit tests. session.run( @@ -81,7 +96,7 @@ def default(session): "--quiet", f"--junitxml=unit_{session.python}_sponge_log.xml", "--cov=grafeas", - "--cov=tests.unit", + "--cov=tests/unit", "--cov-append", "--cov-config=.coveragerc", "--cov-report=", @@ -100,15 +115,18 @@ def unit(session): @nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) def system(session): """Run the system test suite.""" + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) system_test_path = os.path.join("tests", "system.py") system_test_folder_path = os.path.join("tests", "system") # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": session.skip("RUN_SYSTEM_TESTS is set to false, skipping") - # Sanity check: Only run tests if the environment variable is set. - if not os.environ.get("GOOGLE_APPLICATION_CREDENTIALS", ""): - session.skip("Credentials must be set via environment variable") + # Install pyopenssl for mTLS testing. + if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": + session.install("pyopenssl") system_test_exists = os.path.exists(system_test_path) system_test_folder_exists = os.path.exists(system_test_folder_path) @@ -121,10 +139,8 @@ def system(session): # Install all test dependencies, then install this package into the # virtualenv's dist-packages. - session.install( - "mock", "pytest", "google-cloud-testutils", - ) - session.install("-e", ".") + session.install("mock", "pytest", "google-cloud-testutils", "-c", constraints_path) + session.install("-e", ".", "-c", constraints_path) # Run py.test against the system tests. if system_test_exists: @@ -163,7 +179,7 @@ def docs(session): """Build the docs for this library.""" session.install("-e", ".") - session.install("sphinx", "alabaster", "recommonmark") + session.install("sphinx==4.0.1", "alabaster", "recommonmark") shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) session.run( @@ -185,7 +201,9 @@ def docfx(session): """Build the docfx yaml files for this library.""" session.install("-e", ".") - session.install("sphinx", "alabaster", "recommonmark", "gcp-sphinx-docfx-yaml") + session.install( + "sphinx==4.0.1", "alabaster", "recommonmark", "gcp-sphinx-docfx-yaml" + ) shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) session.run( diff --git a/packages/grafeas/synth.py b/packages/grafeas/owlbot.py similarity index 54% rename from packages/grafeas/synth.py rename to packages/grafeas/owlbot.py index 178df608f7bb..25d9ce42a94b 100644 --- a/packages/grafeas/synth.py +++ b/packages/grafeas/owlbot.py @@ -21,75 +21,59 @@ logging.basicConfig(level=logging.DEBUG) -gapic = gcp.GAPICBazel() common = gcp.CommonTemplates() -# ---------------------------------------------------------------------------- -# Generate Grafeas GAPIC layer -# ---------------------------------------------------------------------------- -library = gapic.py_library( - service="grafeas", - version="v1", - bazel_target="//grafeas/v1:grafeas-v1-py", - proto_output_path="grafeas/grafeas_v1/proto", - include_protos=True, -) +default_version = "v1" -excludes = ["README.rst", "setup.py", "docs/index.rst"] +for library in s.get_staging_dirs(default_version): + # Make package name 'grafeas' + s.replace(library / "grafeas/**/*.py", "grafeas-grafeas", "grafeas") -s.move(library, excludes=excludes) + # ---------------------------------------------------------------------------- + # Remove google-specific portions of library + # ---------------------------------------------------------------------------- + # Please see this PR for more context + # https://github.com/googleapis/google-cloud-python/pull/8186/ -# Make package name 'grafeas' -s.replace("grafeas/**/*.py", "grafeas-grafeas", "grafeas") - -# ---------------------------------------------------------------------------- -# Remove google-specific portions of library -# ---------------------------------------------------------------------------- + # Remove default service address, default scopes, default credentials + # Users must pass a transport to the client constructor -# Please see this PR for more context -# https://github.com/googleapis/google-cloud-python/pull/8186/ - -# Remove default service address, default scopes, default credentials -# Users must pass a transport to the client constructor - - -# Remove default endpoint -s.replace( - "grafeas/**/*client.py", - r"""\s+DEFAULT_ENDPOINT\s+=\s+"containeranalysis\.googleapis\.com" + # Remove default endpoint + s.replace( + library / "grafeas/**/*client.py", + r"""\s+DEFAULT_ENDPOINT\s+=\s+"containeranalysis\.googleapis\.com" \s+DEFAULT_MTLS_ENDPOINT\s+=\s+_get_default_mtls_endpoint\.__func__\( # type: ignore \s+DEFAULT_ENDPOINT \s+\)""", "", -) - -s.replace( - "grafeas/**/transports/*.py", r"""'containeranalysis\.googleapis\.com'""", """''""", -) - - -# Remove 'from_service_account_file' method -s.replace( - "grafeas/**/*client.py", + ) + + s.replace( + library / "grafeas/**/*client.py", + """DEFAULT_ENDPOINT = GrafeasClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = GrafeasClient.DEFAULT_MTLS_ENDPOINT""", + """""", + ) + + s.replace( + library / "grafeas/**/transports/*.py", r"""'containeranalysis\.googleapis\.com'""", """''""", + ) + + # Remove 'from_service_account_file' method + s.replace( + library / "grafeas/**/*client.py", """@classmethod def from_service_account_file.* from_service_account_json = from_service_account_file""", "", flags=re.MULTILINE | re.DOTALL, -) - -s.replace( - "grafeas/**/async_client.py", - """\s+from_service_account_file = GrafeasClient\.from_service_account_file -\s+from_service_account_json = from_service_account_file""", - "", -) + ) -# Remove credentials and client options from the service celint -# A transport must be used to initialize the client -s.replace( - "grafeas/**/client.py", + # Remove credentials and client options from the service celint + # A transport must be used to initialize the client + s.replace( + library / "grafeas/**/client.py", """(\s+)def __init__\(self.*?def """, '''\g<1>def __init__(self, *, transport: Union[str, GrafeasTransport] = None, @@ -113,11 +97,11 @@ def from_service_account_file.* self._transport = Transport() \g<1>def ''', flags=re.MULTILINE | re.DOTALL, -) + ) -# do the same for async -s.replace( - "grafeas/**/async_client.py", + # do the same for async + s.replace( + library / "grafeas/**/async_client.py", """(\s+)def __init__\(self.*?async def """, '''\g<1>def __init__(self, *, transport: Union[str, GrafeasTransport] = 'grpc_asyncio', @@ -138,55 +122,73 @@ def from_service_account_file.* ) \g<1>async def ''', flags=re.MULTILINE | re.DOTALL, -) + ) -# Changes tests + # Changes tests -# remove use of credentials -s.replace("tests/**/test_grafeas.py", """credentials=credentials.*?,""", "") + # Remove hardcoded default endpoint + s.replace(library / "tests/**/test_grafeas.py", "containeranalysis.googleapis.com", "") -# remove client_options -s.replace("tests/**/test_grafeas.py", """client_options=\{.*?\},""", "") -s.replace("tests/**/test_grafeas.py", """client_options=options,""", "") -s.replace( - "tests/**/test_grafeas.py", - """client_options=client_options.ClientOptions(.*?),""", - "", -) + # remove use of credentials + s.replace(library / "tests/**/test_grafeas.py", """credentials=ga_credentials.*?,""", "") -# Delete irrelevant tests + # Delete irrelevant tests -# client options tests -s.replace( - "tests/**/test_grafeas.py", + # client options tests + s.replace( + library / "tests/**/test_grafeas.py", """def client_cert_source_callback.*?def test_get_occurrence""", - """def test_get_occurrence""", + """def client_cert_source_callback(): + return b"cert bytes", b"key bytes"\n +def test_get_occurrence""", flags=re.MULTILINE | re.DOTALL, -) + ) -# default endpoint test -s.replace( - "tests/**/test_grafeas.py", + # Remove test_client_withDEFAULT_CLIENT_INFO test + s.replace( + library / "tests/**/test_grafeas.py", + """def test_client_withDEFAULT_CLIENT_INFO.* + prep\.assert_called_once_with\(client_info\)$""", + "", + flags=re.MULTILINE | re.DOTALL, + ) + + # default endpoint test + s.replace( + library / "tests/**/test_grafeas.py", """def test_grafeas_host_no_port.*?def test_grafeas_grpc_transport_channel""", """def test_grafeas_grpc_transport_channel""", flags=re.MULTILINE | re.DOTALL, -) + ) -# duplicate credentials tests -s.replace( - "tests/**/test_grafeas.py", + # duplicate credentials tests + s.replace( + library / "tests/**/test_grafeas.py", """def test_credentials_transport_error.*?def test_transport_instance""", """def test_transport_instance""", flags=re.MULTILINE | re.DOTALL, -) + ) -s.replace( - "tests/**/test_grafeas.py", + s.replace( + library / "tests/**/test_grafeas.py", """def test_grafeas_base_transport_error.*?def test_grafeas_base_transport""", """def test_grafeas_base_transport""", flags=re.MULTILINE | re.DOTALL, -) + ) + + # Work around gapic generator bug https://github.com/googleapis/gapic-generator-python/issues/902 + s.replace(library / f"grafeas/grafeas_{library.name}/types/*.py", + r""". + Attributes:""", + r""".\n + Attributes:""", + ) + + excludes = ["README.rst", "setup.py", "docs/index.rst"] + s.move(library, excludes=excludes) + +s.remove_staging_dirs() # ---------------------------------------------------------------------------- # Add templated files @@ -197,7 +199,7 @@ def from_service_account_file.* ) s.move( - templated_files, excludes=[".coveragerc"] + templated_files, excludes=[".coveragerc", ".github/snippet-bot.yml"] ) # microgenerator has a good .coveragerc file @@ -205,9 +207,8 @@ def from_service_account_file.* s.replace("noxfile.py", """['"]google['"]""", '''"grafeas"''') s.replace( "noxfile.py", - """"--cov=google.cloud.grafeas", - \s+"--cov=google.cloud",""", - """"--cov=grafeas",""", + "--cov=google/cloud", + "--cov=grafeas", ) -s.shell.run(["nox", "-s", "blacken"], hide_output=False) +s.shell.run(["nox", "-s", "blacken"], hide_output=False) \ No newline at end of file diff --git a/packages/grafeas/renovate.json b/packages/grafeas/renovate.json index 4fa949311b20..c04895563e69 100644 --- a/packages/grafeas/renovate.json +++ b/packages/grafeas/renovate.json @@ -1,5 +1,9 @@ { "extends": [ "config:base", ":preserveSemverRanges" - ] + ], + "ignorePaths": [".pre-commit-config.yaml"], + "pip_requirements": { + "fileMatch": ["requirements-test.txt", "samples/[\\S/]*constraints.txt", "samples/[\\S/]*constraints-test.txt"] + } } diff --git a/packages/grafeas/scripts/decrypt-secrets.sh b/packages/grafeas/scripts/decrypt-secrets.sh index ff599eb2af25..21f6d2a26d90 100755 --- a/packages/grafeas/scripts/decrypt-secrets.sh +++ b/packages/grafeas/scripts/decrypt-secrets.sh @@ -20,14 +20,27 @@ ROOT=$( dirname "$DIR" ) # Work from the project root. cd $ROOT +# Prevent it from overriding files. +# We recommend that sample authors use their own service account files and cloud project. +# In that case, they are supposed to prepare these files by themselves. +if [[ -f "testing/test-env.sh" ]] || \ + [[ -f "testing/service-account.json" ]] || \ + [[ -f "testing/client-secrets.json" ]]; then + echo "One or more target files exist, aborting." + exit 1 +fi + # Use SECRET_MANAGER_PROJECT if set, fallback to cloud-devrel-kokoro-resources. PROJECT_ID="${SECRET_MANAGER_PROJECT:-cloud-devrel-kokoro-resources}" gcloud secrets versions access latest --secret="python-docs-samples-test-env" \ + --project="${PROJECT_ID}" \ > testing/test-env.sh gcloud secrets versions access latest \ --secret="python-docs-samples-service-account" \ + --project="${PROJECT_ID}" \ > testing/service-account.json gcloud secrets versions access latest \ --secret="python-docs-samples-client-secrets" \ - > testing/client-secrets.json \ No newline at end of file + --project="${PROJECT_ID}" \ + > testing/client-secrets.json diff --git a/packages/grafeas/scripts/fixup_grafeas_v1_keywords.py b/packages/grafeas/scripts/fixup_grafeas_v1_keywords.py index 8a782dc6e362..f8eaf656a922 100644 --- a/packages/grafeas/scripts/fixup_grafeas_v1_keywords.py +++ b/packages/grafeas/scripts/fixup_grafeas_v1_keywords.py @@ -1,5 +1,5 @@ +#! /usr/bin/env python3 # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import argparse import os import libcst as cst @@ -40,21 +39,20 @@ def partition( 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', ), - + '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: @@ -85,7 +83,7 @@ def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: value=cst.Dict([ cst.DictElement( cst.SimpleString("'{}'".format(name)), - cst.Element(value=arg.value) +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 diff --git a/packages/grafeas/setup.py b/packages/grafeas/setup.py index 573d129e80b3..d4a924445ff6 100644 --- a/packages/grafeas/setup.py +++ b/packages/grafeas/setup.py @@ -26,7 +26,7 @@ dependencies = [ "google-api-core[grpc] >= 1.21.0, < 2.0.0dev", "proto-plus >= 1.4.0", - "libcst >= 0.2.5", + "packaging >= 14.3", ] package_root = os.path.abspath(os.path.dirname(__file__)) diff --git a/packages/grafeas/synth.metadata b/packages/grafeas/synth.metadata deleted file mode 100644 index 8051dc58a281..000000000000 --- a/packages/grafeas/synth.metadata +++ /dev/null @@ -1,37 +0,0 @@ -{ - "sources": [ - { - "git": { - "name": ".", - "remote": "git@github.com:googleapis/python-grafeas", - "sha": "fb7debad7a8793929b91d38f999941b2708d84bd" - } - }, - { - "git": { - "name": "googleapis", - "remote": "https://github.com/googleapis/googleapis.git", - "sha": "96ef637adf148d54236ad83fefa30c7f75f29737", - "internalRef": "325052820" - } - }, - { - "git": { - "name": "synthtool", - "remote": "https://github.com/googleapis/synthtool.git", - "sha": "4530cc6ff080ef8aca258c1ec92c4db10a1bbfb4" - } - } - ], - "destinations": [ - { - "client": { - "source": "googleapis", - "apiName": "grafeas", - "apiVersion": "v1", - "language": "python", - "generator": "bazel" - } - } - ] -} \ No newline at end of file diff --git a/packages/grafeas/testing/constraints-3.6.txt b/packages/grafeas/testing/constraints-3.6.txt index b782f20d9a4a..4fda4298eb99 100644 --- a/packages/grafeas/testing/constraints-3.6.txt +++ b/packages/grafeas/testing/constraints-3.6.txt @@ -5,6 +5,7 @@ # # e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev", # Then this file should have foo==1.14.0 -google-api-core==1.21.0 +google-api-core==1.26.0 proto-plus==1.4.0 -libcst==0.2.5 \ No newline at end of file +packaging==14.3 +google-auth==1.24.0 # TODO: remove when google-auth>=1.25.0 si transitively required through google-api-core diff --git a/packages/grafeas/tests/__init__.py b/packages/grafeas/tests/__init__.py new file mode 100644 index 000000000000..4de65971c238 --- /dev/null +++ b/packages/grafeas/tests/__init__.py @@ -0,0 +1,15 @@ +# -*- 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/packages/grafeas/tests/unit/__init__.py b/packages/grafeas/tests/unit/__init__.py new file mode 100644 index 000000000000..4de65971c238 --- /dev/null +++ b/packages/grafeas/tests/unit/__init__.py @@ -0,0 +1,15 @@ +# -*- 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/packages/grafeas/tests/unit/gapic/__init__.py b/packages/grafeas/tests/unit/gapic/__init__.py new file mode 100644 index 000000000000..4de65971c238 --- /dev/null +++ b/packages/grafeas/tests/unit/gapic/__init__.py @@ -0,0 +1,15 @@ +# -*- 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/packages/grafeas/tests/unit/gapic/grafeas_v1/__init__.py b/packages/grafeas/tests/unit/gapic/grafeas_v1/__init__.py index 8b137891791f..4de65971c238 100644 --- a/packages/grafeas/tests/unit/gapic/grafeas_v1/__init__.py +++ b/packages/grafeas/tests/unit/gapic/grafeas_v1/__init__.py @@ -1 +1,15 @@ - +# -*- 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/packages/grafeas/tests/unit/gapic/grafeas_v1/test_grafeas.py b/packages/grafeas/tests/unit/gapic/grafeas_v1/test_grafeas.py index 3ad70a5e3082..653c12d249e1 100644 --- a/packages/grafeas/tests/unit/gapic/grafeas_v1/test_grafeas.py +++ b/packages/grafeas/tests/unit/gapic/grafeas_v1/test_grafeas.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import os import mock +import packaging.version import grpc from grpc.experimental import aio @@ -24,23 +23,24 @@ import pytest from proto.marshal.rules.dates import DurationRule, TimestampRule -from google import auth + from google.api_core import client_options -from google.api_core import exceptions +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.auth import credentials +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 as any # type: ignore -from google.protobuf import field_mask_pb2 as field_mask # type: ignore -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.rpc import status_pb2 as status # type: ignore +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore 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.services.grafeas.transports.base import _GOOGLE_AUTH_VERSION from grafeas.grafeas_v1.types import attestation from grafeas.grafeas_v1.types import build from grafeas.grafeas_v1.types import common @@ -50,11 +50,28 @@ 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 package as g_package from grafeas.grafeas_v1.types import provenance -from grafeas.grafeas_v1.types import provenance as g_provenance from grafeas.grafeas_v1.types import upgrade from grafeas.grafeas_v1.types import vulnerability +import google.auth + + +# TODO(busunkim): Once google-auth >= 1.25.0 is required transitively +# through google-api-core: +# - Delete the auth "less than" test cases +# - Delete these pytest markers (Make the "greater than or equal to" tests the default). +requires_google_auth_lt_1_25_0 = pytest.mark.skipif( + packaging.version.parse(_GOOGLE_AUTH_VERSION) >= packaging.version.parse("1.25.0"), + reason="This test requires google-auth < 1.25.0", +) +requires_google_auth_gte_1_25_0 = pytest.mark.skipif( + packaging.version.parse(_GOOGLE_AUTH_VERSION) < packaging.version.parse("1.25.0"), + reason="This test requires google-auth >= 1.25.0", +) + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" def test_get_occurrence( @@ -67,7 +84,7 @@ def test_get_occurrence( 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: + 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", @@ -75,28 +92,21 @@ def test_get_occurrence( note_name="note_name_value", kind=common.NoteKind.VULNERABILITY, remediation="remediation_value", - vulnerability=vulnerability.VulnerabilityOccurrence(type="type_value"), + vulnerability=vulnerability.VulnerabilityOccurrence(type_="type__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] - assert args[0] == grafeas.GetOccurrenceRequest() # 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" @@ -104,18 +114,31 @@ def test_get_occurrence_from_dict(): test_get_occurrence(request_type=dict) +def test_get_occurrence_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_occurrence), "__call__") as call: + client.get_occurrence() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.GetOccurrenceRequest() + + @pytest.mark.asyncio -async def test_get_occurrence_async(transport: str = "grpc_asyncio"): +async def test_get_occurrence_async( + transport: str = "grpc_asyncio", request_type=grafeas.GetOccurrenceRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.GetOccurrenceRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_occurrence), "__call__" - ) as call: + 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( @@ -126,41 +149,39 @@ async def test_get_occurrence_async(transport: str = "grpc_asyncio"): 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] - - assert args[0] == request + assert args[0] == grafeas.GetOccurrenceRequest() # 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() # Any value 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: + 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. @@ -180,14 +201,12 @@ async def test_get_occurrence_field_headers_async(): # Any value 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._client._transport.get_occurrence), "__call__" - ) as call: + 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. @@ -204,10 +223,9 @@ def test_get_occurrence_flattened(): client = GrafeasClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_occurrence), "__call__") as call: + 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",) @@ -216,7 +234,6 @@ def test_get_occurrence_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @@ -236,9 +253,7 @@ async def test_get_occurrence_flattened_async(): client = GrafeasAsyncClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_occurrence), "__call__" - ) as call: + 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() @@ -251,7 +266,6 @@ async def test_get_occurrence_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @@ -277,25 +291,20 @@ def test_list_occurrences( 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: + 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] - assert args[0] == grafeas.ListOccurrencesRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListOccurrencesPager) - assert response.next_page_token == "next_page_token_value" @@ -303,51 +312,64 @@ def test_list_occurrences_from_dict(): test_list_occurrences(request_type=dict) +def test_list_occurrences_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_occurrences), "__call__") as call: + client.list_occurrences() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.ListOccurrencesRequest() + + @pytest.mark.asyncio -async def test_list_occurrences_async(transport: str = "grpc_asyncio"): +async def test_list_occurrences_async( + transport: str = "grpc_asyncio", request_type=grafeas.ListOccurrencesRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.ListOccurrencesRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_occurrences), "__call__" - ) as call: + 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] - - assert args[0] == request + assert args[0] == grafeas.ListOccurrencesRequest() # 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() # Any value 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: + 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. @@ -367,16 +389,14 @@ async def test_list_occurrences_field_headers_async(): # Any value 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._client._transport.list_occurrences), "__call__" - ) as call: + 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. @@ -393,12 +413,9 @@ def test_list_occurrences_flattened(): client = GrafeasClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_occurrences), "__call__" - ) as call: + 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( @@ -409,9 +426,7 @@ def test_list_occurrences_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].filter == "filter_value" @@ -433,9 +448,7 @@ async def test_list_occurrences_flattened_async(): client = GrafeasAsyncClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_occurrences), "__call__" - ) as call: + 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() @@ -452,9 +465,7 @@ async def test_list_occurrences_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].filter == "filter_value" @@ -476,9 +487,7 @@ def test_list_occurrences_pager(): client = GrafeasClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_occurrences), "__call__" - ) as call: + 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( @@ -516,9 +525,7 @@ def test_list_occurrences_pages(): client = GrafeasClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_occurrences), "__call__" - ) as call: + 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( @@ -539,8 +546,8 @@ def test_list_occurrences_pages(): 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 + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -549,9 +556,7 @@ async def test_list_occurrences_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_occurrences), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_occurrences), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -588,9 +593,7 @@ async def test_list_occurrences_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_occurrences), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_occurrences), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -612,10 +615,10 @@ async def test_list_occurrences_async_pages(): RuntimeError, ) pages = [] - async for page in (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 + async for page_ in (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 def test_delete_occurrence( @@ -629,17 +632,15 @@ def test_delete_occurrence( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.delete_occurrence), "__call__" + 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] - assert args[0] == grafeas.DeleteOccurrenceRequest() # Establish that the response is the type that we expect. @@ -650,47 +651,67 @@ def test_delete_occurrence_from_dict(): test_delete_occurrence(request_type=dict) +def test_delete_occurrence_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_occurrence), "__call__" + ) as call: + client.delete_occurrence() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.DeleteOccurrenceRequest() + + @pytest.mark.asyncio -async def test_delete_occurrence_async(transport: str = "grpc_asyncio"): +async def test_delete_occurrence_async( + transport: str = "grpc_asyncio", request_type=grafeas.DeleteOccurrenceRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.DeleteOccurrenceRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.delete_occurrence), "__call__" + 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] - - assert args[0] == request + assert args[0] == grafeas.DeleteOccurrenceRequest() # 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() # Any value 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__" + 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. @@ -710,14 +731,14 @@ async def test_delete_occurrence_field_headers_async(): # Any value 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._client._transport.delete_occurrence), "__call__" + 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. @@ -735,11 +756,10 @@ def test_delete_occurrence_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.delete_occurrence), "__call__" + 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",) @@ -748,7 +768,6 @@ def test_delete_occurrence_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @@ -769,7 +788,7 @@ async def test_delete_occurrence_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.delete_occurrence), "__call__" + type(client.transport.delete_occurrence), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = None @@ -783,7 +802,6 @@ async def test_delete_occurrence_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @@ -810,7 +828,7 @@ def test_create_occurrence( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.create_occurrence), "__call__" + type(client.transport.create_occurrence), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grafeas.Occurrence( @@ -819,28 +837,21 @@ def test_create_occurrence( note_name="note_name_value", kind=common.NoteKind.VULNERABILITY, remediation="remediation_value", - vulnerability=vulnerability.VulnerabilityOccurrence(type="type_value"), + vulnerability=vulnerability.VulnerabilityOccurrence(type_="type__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] - assert args[0] == grafeas.CreateOccurrenceRequest() # 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" @@ -848,17 +859,34 @@ def test_create_occurrence_from_dict(): test_create_occurrence(request_type=dict) +def test_create_occurrence_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_occurrence), "__call__" + ) as call: + client.create_occurrence() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.CreateOccurrenceRequest() + + @pytest.mark.asyncio -async def test_create_occurrence_async(transport: str = "grpc_asyncio"): +async def test_create_occurrence_async( + transport: str = "grpc_asyncio", request_type=grafeas.CreateOccurrenceRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.CreateOccurrenceRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.create_occurrence), "__call__" + type(client.transport.create_occurrence), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -870,43 +898,41 @@ async def test_create_occurrence_async(transport: str = "grpc_asyncio"): 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] - - assert args[0] == request + assert args[0] == grafeas.CreateOccurrenceRequest() # 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() # Any value 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__" + 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. @@ -926,14 +952,14 @@ async def test_create_occurrence_field_headers_async(): # Any value 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._client._transport.create_occurrence), "__call__" + 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. @@ -951,11 +977,10 @@ def test_create_occurrence_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.create_occurrence), "__call__" + 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( @@ -966,9 +991,7 @@ def test_create_occurrence_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].occurrence == grafeas.Occurrence(name="name_value") @@ -991,7 +1014,7 @@ async def test_create_occurrence_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.create_occurrence), "__call__" + type(client.transport.create_occurrence), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grafeas.Occurrence() @@ -1007,9 +1030,7 @@ async def test_create_occurrence_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].occurrence == grafeas.Occurrence(name="name_value") @@ -1038,17 +1059,15 @@ def test_batch_create_occurrences( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.batch_create_occurrences), "__call__" + 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] - assert args[0] == grafeas.BatchCreateOccurrencesRequest() # Establish that the response is the type that we expect. @@ -1059,49 +1078,69 @@ def test_batch_create_occurrences_from_dict(): test_batch_create_occurrences(request_type=dict) +def test_batch_create_occurrences_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # 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: + client.batch_create_occurrences() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.BatchCreateOccurrencesRequest() + + @pytest.mark.asyncio -async def test_batch_create_occurrences_async(transport: str = "grpc_asyncio"): +async def test_batch_create_occurrences_async( + transport: str = "grpc_asyncio", request_type=grafeas.BatchCreateOccurrencesRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.BatchCreateOccurrencesRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.batch_create_occurrences), "__call__" + 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] - - assert args[0] == request + assert args[0] == grafeas.BatchCreateOccurrencesRequest() # 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() # Any value 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__" + 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. @@ -1121,16 +1160,16 @@ async def test_batch_create_occurrences_field_headers_async(): # Any value 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._client._transport.batch_create_occurrences), "__call__" + 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. @@ -1148,11 +1187,10 @@ def test_batch_create_occurrences_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.batch_create_occurrences), "__call__" + 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( @@ -1163,9 +1201,7 @@ def test_batch_create_occurrences_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].occurrences == [grafeas.Occurrence(name="name_value")] @@ -1188,7 +1224,7 @@ async def test_batch_create_occurrences_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.batch_create_occurrences), "__call__" + type(client.transport.batch_create_occurrences), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grafeas.BatchCreateOccurrencesResponse() @@ -1206,9 +1242,7 @@ async def test_batch_create_occurrences_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].occurrences == [grafeas.Occurrence(name="name_value")] @@ -1237,7 +1271,7 @@ def test_update_occurrence( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.update_occurrence), "__call__" + type(client.transport.update_occurrence), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grafeas.Occurrence( @@ -1246,28 +1280,21 @@ def test_update_occurrence( note_name="note_name_value", kind=common.NoteKind.VULNERABILITY, remediation="remediation_value", - vulnerability=vulnerability.VulnerabilityOccurrence(type="type_value"), + vulnerability=vulnerability.VulnerabilityOccurrence(type_="type__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] - assert args[0] == grafeas.UpdateOccurrenceRequest() # 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" @@ -1275,17 +1302,34 @@ def test_update_occurrence_from_dict(): test_update_occurrence(request_type=dict) +def test_update_occurrence_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_occurrence), "__call__" + ) as call: + client.update_occurrence() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.UpdateOccurrenceRequest() + + @pytest.mark.asyncio -async def test_update_occurrence_async(transport: str = "grpc_asyncio"): +async def test_update_occurrence_async( + transport: str = "grpc_asyncio", request_type=grafeas.UpdateOccurrenceRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.UpdateOccurrenceRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.update_occurrence), "__call__" + type(client.transport.update_occurrence), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -1297,43 +1341,41 @@ async def test_update_occurrence_async(transport: str = "grpc_asyncio"): 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] - - assert args[0] == request + assert args[0] == grafeas.UpdateOccurrenceRequest() # 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() # Any value 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__" + 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. @@ -1353,14 +1395,14 @@ async def test_update_occurrence_field_headers_async(): # Any value 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._client._transport.update_occurrence), "__call__" + 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. @@ -1378,29 +1420,25 @@ def test_update_occurrence_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.update_occurrence), "__call__" + 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.FieldMask(paths=["paths_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] - assert args[0].name == "name_value" - assert args[0].occurrence == grafeas.Occurrence(name="name_value") - - assert args[0].update_mask == field_mask.FieldMask(paths=["paths_value"]) + assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) def test_update_occurrence_flattened_error(): @@ -1413,7 +1451,7 @@ def test_update_occurrence_flattened_error(): grafeas.UpdateOccurrenceRequest(), name="name_value", occurrence=grafeas.Occurrence(name="name_value"), - update_mask=field_mask.FieldMask(paths=["paths_value"]), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) @@ -1423,7 +1461,7 @@ async def test_update_occurrence_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.update_occurrence), "__call__" + type(client.transport.update_occurrence), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grafeas.Occurrence() @@ -1434,19 +1472,16 @@ async def test_update_occurrence_flattened_async(): response = await client.update_occurrence( name="name_value", occurrence=grafeas.Occurrence(name="name_value"), - update_mask=field_mask.FieldMask(paths=["paths_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] - assert args[0].name == "name_value" - assert args[0].occurrence == grafeas.Occurrence(name="name_value") - - assert args[0].update_mask == field_mask.FieldMask(paths=["paths_value"]) + assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) @pytest.mark.asyncio @@ -1460,7 +1495,7 @@ async def test_update_occurrence_flattened_error_async(): grafeas.UpdateOccurrenceRequest(), name="name_value", occurrence=grafeas.Occurrence(name="name_value"), - update_mask=field_mask.FieldMask(paths=["paths_value"]), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) @@ -1475,7 +1510,7 @@ def test_get_occurrence_note( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_occurrence_note), "__call__" + type(client.transport.get_occurrence_note), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grafeas.Note( @@ -1486,26 +1521,19 @@ def test_get_occurrence_note( related_note_names=["related_note_names_value"], vulnerability=vulnerability.VulnerabilityNote(cvss_score=0.1082), ) - 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] - assert args[0] == grafeas.GetOccurrenceNoteRequest() # 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"] @@ -1513,17 +1541,34 @@ def test_get_occurrence_note_from_dict(): test_get_occurrence_note(request_type=dict) +def test_get_occurrence_note_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # 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: + client.get_occurrence_note() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.GetOccurrenceNoteRequest() + + @pytest.mark.asyncio -async def test_get_occurrence_note_async(transport: str = "grpc_asyncio"): +async def test_get_occurrence_note_async( + transport: str = "grpc_asyncio", request_type=grafeas.GetOccurrenceNoteRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.GetOccurrenceNoteRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_occurrence_note), "__call__" + type(client.transport.get_occurrence_note), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -1535,43 +1580,41 @@ async def test_get_occurrence_note_async(transport: str = "grpc_asyncio"): 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] - - assert args[0] == request + assert args[0] == grafeas.GetOccurrenceNoteRequest() # 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() # Any value 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__" + 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. @@ -1591,14 +1634,14 @@ async def test_get_occurrence_note_field_headers_async(): # Any value 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._client._transport.get_occurrence_note), "__call__" + 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. @@ -1616,11 +1659,10 @@ def test_get_occurrence_note_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.get_occurrence_note), "__call__" + 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",) @@ -1629,7 +1671,6 @@ def test_get_occurrence_note_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @@ -1650,7 +1691,7 @@ async def test_get_occurrence_note_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.get_occurrence_note), "__call__" + type(client.transport.get_occurrence_note), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grafeas.Note() @@ -1664,7 +1705,6 @@ async def test_get_occurrence_note_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @@ -1688,7 +1728,7 @@ def test_get_note(transport: str = "grpc", request_type=grafeas.GetNoteRequest): 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: + 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", @@ -1698,26 +1738,19 @@ def test_get_note(transport: str = "grpc", request_type=grafeas.GetNoteRequest): related_note_names=["related_note_names_value"], vulnerability=vulnerability.VulnerabilityNote(cvss_score=0.1082), ) - 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] - assert args[0] == grafeas.GetNoteRequest() # 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"] @@ -1725,18 +1758,31 @@ def test_get_note_from_dict(): test_get_note(request_type=dict) +def test_get_note_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_note), "__call__") as call: + client.get_note() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.GetNoteRequest() + + @pytest.mark.asyncio -async def test_get_note_async(transport: str = "grpc_asyncio"): +async def test_get_note_async( + transport: str = "grpc_asyncio", request_type=grafeas.GetNoteRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.GetNoteRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_note), "__call__" - ) as call: + 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( @@ -1747,41 +1793,39 @@ async def test_get_note_async(transport: str = "grpc_asyncio"): 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] - - assert args[0] == request + assert args[0] == grafeas.GetNoteRequest() # 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() # Any value 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: + 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. @@ -1801,14 +1845,12 @@ async def test_get_note_field_headers_async(): # Any value 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._client._transport.get_note), "__call__" - ) as call: + 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. @@ -1825,10 +1867,9 @@ def test_get_note_flattened(): client = GrafeasClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_note), "__call__") as call: + 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",) @@ -1837,7 +1878,6 @@ def test_get_note_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @@ -1857,9 +1897,7 @@ async def test_get_note_flattened_async(): client = GrafeasAsyncClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.get_note), "__call__" - ) as call: + 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() @@ -1872,7 +1910,6 @@ async def test_get_note_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @@ -1896,23 +1933,20 @@ def test_list_notes(transport: str = "grpc", request_type=grafeas.ListNotesReque 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: + 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] - assert args[0] == grafeas.ListNotesRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListNotesPager) - assert response.next_page_token == "next_page_token_value" @@ -1920,49 +1954,64 @@ def test_list_notes_from_dict(): test_list_notes(request_type=dict) +def test_list_notes_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_notes), "__call__") as call: + client.list_notes() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.ListNotesRequest() + + @pytest.mark.asyncio -async def test_list_notes_async(transport: str = "grpc_asyncio"): +async def test_list_notes_async( + transport: str = "grpc_asyncio", request_type=grafeas.ListNotesRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.ListNotesRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_notes), "__call__" - ) as call: + 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] - - assert args[0] == request + assert args[0] == grafeas.ListNotesRequest() # 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() # Any value 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: + 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. @@ -1982,16 +2031,14 @@ async def test_list_notes_field_headers_async(): # Any value 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._client._transport.list_notes), "__call__" - ) as call: + 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. @@ -2008,10 +2055,9 @@ def test_list_notes_flattened(): client = GrafeasClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_notes), "__call__") as call: + 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( @@ -2022,9 +2068,7 @@ def test_list_notes_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].filter == "filter_value" @@ -2044,9 +2088,7 @@ async def test_list_notes_flattened_async(): client = GrafeasAsyncClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.list_notes), "__call__" - ) as call: + 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() @@ -2063,9 +2105,7 @@ async def test_list_notes_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].filter == "filter_value" @@ -2085,7 +2125,7 @@ def test_list_notes_pager(): client = GrafeasClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_notes), "__call__") as call: + 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( @@ -2115,7 +2155,7 @@ def test_list_notes_pages(): client = GrafeasClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_notes), "__call__") as call: + 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( @@ -2128,8 +2168,8 @@ def test_list_notes_pages(): 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 + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -2138,9 +2178,7 @@ async def test_list_notes_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_notes), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_notes), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -2169,9 +2207,7 @@ async def test_list_notes_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_notes), - "__call__", - new_callable=mock.AsyncMock, + type(client.transport.list_notes), "__call__", new_callable=mock.AsyncMock ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -2185,10 +2221,10 @@ async def test_list_notes_async_pages(): RuntimeError, ) pages = [] - async for page in (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 + async for page_ in (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 def test_delete_note(transport: str = "grpc", request_type=grafeas.DeleteNoteRequest): @@ -2199,16 +2235,14 @@ def test_delete_note(transport: str = "grpc", request_type=grafeas.DeleteNoteReq 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: + 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] - assert args[0] == grafeas.DeleteNoteRequest() # Establish that the response is the type that we expect. @@ -2219,45 +2253,61 @@ def test_delete_note_from_dict(): test_delete_note(request_type=dict) +def test_delete_note_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_note), "__call__") as call: + client.delete_note() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.DeleteNoteRequest() + + @pytest.mark.asyncio -async def test_delete_note_async(transport: str = "grpc_asyncio"): +async def test_delete_note_async( + transport: str = "grpc_asyncio", request_type=grafeas.DeleteNoteRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.DeleteNoteRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_note), "__call__" - ) as call: + 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] - - assert args[0] == request + assert args[0] == grafeas.DeleteNoteRequest() # 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() # Any value 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: + 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. @@ -2277,14 +2327,12 @@ async def test_delete_note_field_headers_async(): # Any value 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._client._transport.delete_note), "__call__" - ) as call: + 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. @@ -2301,10 +2349,9 @@ def test_delete_note_flattened(): client = GrafeasClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.delete_note), "__call__") as call: + 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",) @@ -2313,7 +2360,6 @@ def test_delete_note_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @@ -2333,9 +2379,7 @@ async def test_delete_note_flattened_async(): client = GrafeasAsyncClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.delete_note), "__call__" - ) as call: + with mock.patch.object(type(client.transport.delete_note), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = None @@ -2348,7 +2392,6 @@ async def test_delete_note_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @@ -2372,7 +2415,7 @@ def test_create_note(transport: str = "grpc", request_type=grafeas.CreateNoteReq 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: + 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", @@ -2382,26 +2425,19 @@ def test_create_note(transport: str = "grpc", request_type=grafeas.CreateNoteReq related_note_names=["related_note_names_value"], vulnerability=vulnerability.VulnerabilityNote(cvss_score=0.1082), ) - 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] - assert args[0] == grafeas.CreateNoteRequest() # 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"] @@ -2409,18 +2445,31 @@ def test_create_note_from_dict(): test_create_note(request_type=dict) +def test_create_note_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_note), "__call__") as call: + client.create_note() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.CreateNoteRequest() + + @pytest.mark.asyncio -async def test_create_note_async(transport: str = "grpc_asyncio"): +async def test_create_note_async( + transport: str = "grpc_asyncio", request_type=grafeas.CreateNoteRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.CreateNoteRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_note), "__call__" - ) as call: + 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( @@ -2431,41 +2480,39 @@ async def test_create_note_async(transport: str = "grpc_asyncio"): 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] - - assert args[0] == request + assert args[0] == grafeas.CreateNoteRequest() # 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() # Any value 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: + 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. @@ -2485,14 +2532,12 @@ async def test_create_note_field_headers_async(): # Any value 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._client._transport.create_note), "__call__" - ) as call: + 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. @@ -2509,10 +2554,9 @@ def test_create_note_flattened(): client = GrafeasClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.create_note), "__call__") as call: + 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( @@ -2525,11 +2569,8 @@ def test_create_note_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].note_id == "note_id_value" - assert args[0].note == grafeas.Note(name="name_value") @@ -2552,9 +2593,7 @@ async def test_create_note_flattened_async(): client = GrafeasAsyncClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.create_note), "__call__" - ) as call: + 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() @@ -2571,11 +2610,8 @@ async def test_create_note_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].note_id == "note_id_value" - assert args[0].note == grafeas.Note(name="name_value") @@ -2605,17 +2641,15 @@ def test_batch_create_notes( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.batch_create_notes), "__call__" + 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] - assert args[0] == grafeas.BatchCreateNotesRequest() # Establish that the response is the type that we expect. @@ -2626,49 +2660,69 @@ def test_batch_create_notes_from_dict(): test_batch_create_notes(request_type=dict) +def test_batch_create_notes_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # 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: + client.batch_create_notes() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.BatchCreateNotesRequest() + + @pytest.mark.asyncio -async def test_batch_create_notes_async(transport: str = "grpc_asyncio"): +async def test_batch_create_notes_async( + transport: str = "grpc_asyncio", request_type=grafeas.BatchCreateNotesRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.BatchCreateNotesRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.batch_create_notes), "__call__" + 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] - - assert args[0] == request + assert args[0] == grafeas.BatchCreateNotesRequest() # 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() # Any value 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__" + 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. @@ -2688,16 +2742,16 @@ async def test_batch_create_notes_field_headers_async(): # Any value 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._client._transport.batch_create_notes), "__call__" + 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. @@ -2715,11 +2769,10 @@ def test_batch_create_notes_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.batch_create_notes), "__call__" + 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( @@ -2730,9 +2783,7 @@ def test_batch_create_notes_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].notes == {"key_value": grafeas.Note(name="name_value")} @@ -2755,7 +2806,7 @@ async def test_batch_create_notes_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.batch_create_notes), "__call__" + type(client.transport.batch_create_notes), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grafeas.BatchCreateNotesResponse() @@ -2773,9 +2824,7 @@ async def test_batch_create_notes_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].notes == {"key_value": grafeas.Note(name="name_value")} @@ -2801,7 +2850,7 @@ def test_update_note(transport: str = "grpc", request_type=grafeas.UpdateNoteReq 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: + 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", @@ -2811,26 +2860,19 @@ def test_update_note(transport: str = "grpc", request_type=grafeas.UpdateNoteReq related_note_names=["related_note_names_value"], vulnerability=vulnerability.VulnerabilityNote(cvss_score=0.1082), ) - 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] - assert args[0] == grafeas.UpdateNoteRequest() # 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"] @@ -2838,18 +2880,31 @@ def test_update_note_from_dict(): test_update_note(request_type=dict) +def test_update_note_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_note), "__call__") as call: + client.update_note() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.UpdateNoteRequest() + + @pytest.mark.asyncio -async def test_update_note_async(transport: str = "grpc_asyncio"): +async def test_update_note_async( + transport: str = "grpc_asyncio", request_type=grafeas.UpdateNoteRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.UpdateNoteRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_note), "__call__" - ) as call: + 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( @@ -2860,41 +2915,39 @@ async def test_update_note_async(transport: str = "grpc_asyncio"): 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] - - assert args[0] == request + assert args[0] == grafeas.UpdateNoteRequest() # 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() # Any value 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: + 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. @@ -2914,14 +2967,12 @@ async def test_update_note_field_headers_async(): # Any value 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._client._transport.update_note), "__call__" - ) as call: + 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. @@ -2938,28 +2989,24 @@ def test_update_note_flattened(): client = GrafeasClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.update_note), "__call__") as call: + 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.FieldMask(paths=["paths_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] - assert args[0].name == "name_value" - assert args[0].note == grafeas.Note(name="name_value") - - assert args[0].update_mask == field_mask.FieldMask(paths=["paths_value"]) + assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) def test_update_note_flattened_error(): @@ -2972,7 +3019,7 @@ def test_update_note_flattened_error(): grafeas.UpdateNoteRequest(), name="name_value", note=grafeas.Note(name="name_value"), - update_mask=field_mask.FieldMask(paths=["paths_value"]), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) @@ -2981,9 +3028,7 @@ async def test_update_note_flattened_async(): client = GrafeasAsyncClient() # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._client._transport.update_note), "__call__" - ) as call: + 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() @@ -2993,19 +3038,16 @@ async def test_update_note_flattened_async(): response = await client.update_note( name="name_value", note=grafeas.Note(name="name_value"), - update_mask=field_mask.FieldMask(paths=["paths_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] - assert args[0].name == "name_value" - assert args[0].note == grafeas.Note(name="name_value") - - assert args[0].update_mask == field_mask.FieldMask(paths=["paths_value"]) + assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) @pytest.mark.asyncio @@ -3019,7 +3061,7 @@ async def test_update_note_flattened_error_async(): grafeas.UpdateNoteRequest(), name="name_value", note=grafeas.Note(name="name_value"), - update_mask=field_mask.FieldMask(paths=["paths_value"]), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) @@ -3034,24 +3076,21 @@ def test_list_note_occurrences( # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_note_occurrences), "__call__" + 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] - assert args[0] == grafeas.ListNoteOccurrencesRequest() # Establish that the response is the type that we expect. assert isinstance(response, pagers.ListNoteOccurrencesPager) - assert response.next_page_token == "next_page_token_value" @@ -3059,17 +3098,34 @@ def test_list_note_occurrences_from_dict(): test_list_note_occurrences(request_type=dict) +def test_list_note_occurrences_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = GrafeasClient(transport="grpc",) + + # 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: + client.list_note_occurrences() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == grafeas.ListNoteOccurrencesRequest() + + @pytest.mark.asyncio -async def test_list_note_occurrences_async(transport: str = "grpc_asyncio"): +async def test_list_note_occurrences_async( + transport: str = "grpc_asyncio", request_type=grafeas.ListNoteOccurrencesRequest +): client = GrafeasAsyncClient(transport=transport,) # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. - request = grafeas.ListNoteOccurrencesRequest() + request = request_type() # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_note_occurrences), "__call__" + type(client.transport.list_note_occurrences), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( @@ -3077,35 +3133,37 @@ async def test_list_note_occurrences_async(transport: str = "grpc_asyncio"): 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] - - assert args[0] == request + assert args[0] == grafeas.ListNoteOccurrencesRequest() # 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() # Any value 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__" + 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. @@ -3125,16 +3183,16 @@ async def test_list_note_occurrences_field_headers_async(): # Any value 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._client._transport.list_note_occurrences), "__call__" + 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. @@ -3152,11 +3210,10 @@ def test_list_note_occurrences_flattened(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_note_occurrences), "__call__" + 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( @@ -3167,9 +3224,7 @@ def test_list_note_occurrences_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].filter == "filter_value" @@ -3192,7 +3247,7 @@ async def test_list_note_occurrences_flattened_async(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_note_occurrences), "__call__" + type(client.transport.list_note_occurrences), "__call__" ) as call: # Designate an appropriate return value for the call. call.return_value = grafeas.ListNoteOccurrencesResponse() @@ -3210,9 +3265,7 @@ async def test_list_note_occurrences_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].filter == "filter_value" @@ -3235,7 +3288,7 @@ def test_list_note_occurrences_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_note_occurrences), "__call__" + type(client.transport.list_note_occurrences), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -3275,7 +3328,7 @@ def test_list_note_occurrences_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._transport.list_note_occurrences), "__call__" + type(client.transport.list_note_occurrences), "__call__" ) as call: # Set the response to a series of pages. call.side_effect = ( @@ -3297,8 +3350,8 @@ def test_list_note_occurrences_pages(): 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 + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token @pytest.mark.asyncio @@ -3307,7 +3360,7 @@ async def test_list_note_occurrences_async_pager(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_note_occurrences), + type(client.transport.list_note_occurrences), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -3346,7 +3399,7 @@ async def test_list_note_occurrences_async_pages(): # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( - type(client._client._transport.list_note_occurrences), + type(client.transport.list_note_occurrences), "__call__", new_callable=mock.AsyncMock, ) as call: @@ -3370,17 +3423,17 @@ async def test_list_note_occurrences_async_pages(): RuntimeError, ) pages = [] - async for page in (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 + async for page_ in (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_transport_instance(): # A client may be instantiated with a custom transport instance. transport = transports.GrafeasGrpcTransport() client = GrafeasClient(transport=transport) - assert client._transport is transport + assert client.transport is transport def test_transport_get_channel(): @@ -3394,10 +3447,22 @@ def test_transport_get_channel(): assert channel +@pytest.mark.parametrize( + "transport_class", + [transports.GrafeasGrpcTransport, transports.GrafeasGrpcAsyncIOTransport,], +) +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_grpc_default(): # A client should use the gRPC transport by default. client = GrafeasClient() - assert isinstance(client._transport, transports.GrafeasGrpcTransport,) + assert isinstance(client.transport, transports.GrafeasGrpcTransport,) def test_grafeas_base_transport(): @@ -3431,15 +3496,37 @@ def test_grafeas_base_transport(): getattr(transport, method)(request=object()) +@requires_google_auth_gte_1_25_0 def test_grafeas_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( - auth, "load_credentials_from_file" + 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", + ) + + +@requires_google_auth_lt_1_25_0 +def test_grafeas_base_transport_with_credentials_file_old_google_auth(): + # 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 = (credentials.AnonymousCredentials(), None) + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.GrafeasTransport( credentials_file="credentials.json", quota_project_id="octopus", ) @@ -3448,67 +3535,287 @@ def test_grafeas_base_transport_with_credentials_file(): ) +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() + + +@requires_google_auth_gte_1_25_0 def test_grafeas_auth_adc(): # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) + 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, + ) + + +@requires_google_auth_lt_1_25_0 +def test_grafeas_auth_adc_old_google_auth(): + # 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=(), quota_project_id=None, ) -def test_grafeas_transport_auth_adc(): +@pytest.mark.parametrize( + "transport_class", + [transports.GrafeasGrpcTransport, transports.GrafeasGrpcAsyncIOTransport,], +) +@requires_google_auth_gte_1_25_0 +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(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transports.GrafeasGrpcTransport( - host="squid.clam.whelk", quota_project_id="octopus" + 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,], +) +@requires_google_auth_lt_1_25_0 +def test_grafeas_transport_auth_adc_old_google_auth(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") adc.assert_called_once_with( scopes=(), quota_project_id="octopus", ) +@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( + ":443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=(), + scopes=["1", "2"], + default_host="", + 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=(), + 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_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.GrafeasGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called + assert transport._ssl_channel_credentials == None def test_grafeas_grpc_asyncio_transport_channel(): - channel = aio.insecure_channel("http://localhost/") + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() + # Check that channel is used if provided. transport = transports.GrafeasGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, + host="squid.clam.whelk", channel=channel, ) assert transport.grpc_channel == channel assert transport._host == "squid.clam.whelk:443" - assert not callback.called + assert transport._ssl_channel_credentials == None -def test_occurrence_path(): +# 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=(), + 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=(), + 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" - occurrence = "clam" + 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, ) @@ -3518,8 +3825,8 @@ def test_occurrence_path(): def test_parse_occurrence_path(): expected = { - "project": "whelk", - "occurrence": "octopus", + "project": "cuttlefish", + "occurrence": "mussel", } path = GrafeasClient.occurrence_path(**expected) @@ -3528,22 +3835,115 @@ def test_parse_occurrence_path(): assert expected == actual -def test_note_path(): - project = "squid" - note = "clam" +def test_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project,) + actual = GrafeasClient.project_path(project) + assert expected == actual - expected = "projects/{project}/notes/{note}".format(project=project, note=note,) - actual = GrafeasClient.note_path(project, note) + +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_parse_note_path(): +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 = { - "project": "whelk", - "note": "octopus", + "billing_account": "abalone", } - path = GrafeasClient.note_path(**expected) + path = GrafeasClient.common_billing_account_path(**expected) # Check that the path construction is reversible. - actual = GrafeasClient.parse_note_path(path) + 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