diff --git a/.coveragerc b/.coveragerc
index f899817a..86c446a3 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,27 +1,11 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright 2020 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Generated by synthtool. DO NOT EDIT!
[run]
branch = True
[report]
fail_under = 100
show_missing = True
-omit = google/cloud/asset/__init__.py
+omit =
+ google/cloud/asset/__init__.py
exclude_lines =
# Re-enable the standard pragma
pragma: NO COVER
diff --git a/.github/header-checker-lint.yml b/.github/header-checker-lint.yml
new file mode 100644
index 00000000..fc281c05
--- /dev/null
+++ b/.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"],
+ "sourceFileExtensions": [
+ "ts",
+ "js",
+ "java",
+ "sh",
+ "Dockerfile",
+ "yaml",
+ "py",
+ "html",
+ "txt"
+ ]
+}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index b9daa52f..b4243ced 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,8 +50,10 @@ docs.metadata
# Virtual environment
env/
+
+# Test logs
coverage.xml
-sponge_log.xml
+*sponge_log.xml
# System test environment variables.
system_tests/local_test_setup
diff --git a/.kokoro/build.sh b/.kokoro/build.sh
index ab94c0f1..f11a5c7f 100755
--- a/.kokoro/build.sh
+++ b/.kokoro/build.sh
@@ -15,7 +15,11 @@
set -eo pipefail
-cd github/python-asset
+if [[ -z "${PROJECT_ROOT:-}" ]]; then
+ PROJECT_ROOT="github/python-asset"
+fi
+
+cd "${PROJECT_ROOT}"
# Disable buffering, so that the logs stream through.
export PYTHONUNBUFFERED=1
@@ -30,16 +34,26 @@ 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.
+if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]]; then
+ cleanup() {
+ chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot
+ $KOKORO_GFILE_DIR/linux_amd64/flakybot
+ }
+ trap cleanup EXIT HUP
+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
+ python3 -m nox
fi
diff --git a/.kokoro/docs/docs-presubmit.cfg b/.kokoro/docs/docs-presubmit.cfg
index 11181078..f50f3fbc 100644
--- a/.kokoro/docs/docs-presubmit.cfg
+++ b/.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-asset/.kokoro/build.sh"
+}
+
+# Only run this nox session.
+env_vars: {
+ key: "NOX_SESSION"
+ value: "docs docfx"
+}
diff --git a/.kokoro/samples/python3.6/periodic-head.cfg b/.kokoro/samples/python3.6/periodic-head.cfg
new file mode 100644
index 00000000..f9cfcd33
--- /dev/null
+++ b/.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/.kokoro/samples/python3.7/periodic-head.cfg b/.kokoro/samples/python3.7/periodic-head.cfg
new file mode 100644
index 00000000..f9cfcd33
--- /dev/null
+++ b/.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/.kokoro/samples/python3.8/periodic-head.cfg b/.kokoro/samples/python3.8/periodic-head.cfg
new file mode 100644
index 00000000..f9cfcd33
--- /dev/null
+++ b/.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/.kokoro/test-samples-against-head.sh b/.kokoro/test-samples-against-head.sh
new file mode 100755
index 00000000..1a00532b
--- /dev/null
+++ b/.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-asset
+
+exec .kokoro/test-samples-impl.sh
diff --git a/.kokoro/test-samples-impl.sh b/.kokoro/test-samples-impl.sh
new file mode 100755
index 00000000..cf5de74c
--- /dev/null
+++ b/.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/.kokoro/test-samples.sh b/.kokoro/test-samples.sh
index a6781eac..adec5700 100755
--- a/.kokoro/test-samples.sh
+++ b/.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,87 +28,19 @@ cd github/python-asset
# 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
-
-# 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
+ 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"
+exec .kokoro/test-samples-impl.sh
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index a9024b15..32302e48 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -12,6 +12,6 @@ repos:
hooks:
- id: black
- repo: https://gitlab.com/pycqa/flake8
- rev: 3.8.4
+ rev: 3.9.0
hooks:
- id: flake8
diff --git a/.trampolinerc b/.trampolinerc
index 995ee291..383b6ec8 100644
--- a/.trampolinerc
+++ b/.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/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 35bf37c0..4f753672 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -70,9 +70,14 @@ We use `nox `__ to instrument our tests.
- To test your changes, run unit tests with ``nox``::
$ nox -s unit-2.7
- $ nox -s unit-3.7
+ $ nox -s unit-3.8
$ ...
+- Args to pytest can be passed through the nox command separated by a `--`. For
+ example, to run a single test::
+
+ $ nox -s unit-3.8 -- -k
+
.. note::
The unit tests and system tests are described in the
@@ -93,8 +98,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::
+
+ $ nox -s blacken
-- PEP8 compliance, with exceptions defined in the linter configuration.
+- 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::
@@ -133,13 +142,18 @@ Running System Tests
- To run system tests, you can execute::
- $ nox -s system-3.7
+ # Run all system tests
+ $ nox -s system-3.8
$ nox -s system-2.7
+ # 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
+ 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
diff --git a/MANIFEST.in b/MANIFEST.in
index e9e29d12..e783f4c6 100644
--- a/MANIFEST.in
+++ b/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/UPGRADING.md b/UPGRADING.md
index f6c670c8..11bb021c 100644
--- a/UPGRADING.md
+++ b/UPGRADING.md
@@ -17,10 +17,10 @@ The 2.0.0 release requires Python 3.6+.
Methods expect request objects. We provide a script that will convert most common use cases.
-* Install the library
+* Install the library with `libcst`.
```py
-python3 -m pip install google-cloud-asset
+python3 -m pip install google-cloud-asset[libcst]
```
* The script `fixup_asset_v1_keywords.py` is shipped with the library. It expects
diff --git a/docs/asset_v1/asset_service.rst b/docs/asset_v1/asset_service.rst
new file mode 100644
index 00000000..46426270
--- /dev/null
+++ b/docs/asset_v1/asset_service.rst
@@ -0,0 +1,11 @@
+AssetService
+------------------------------
+
+.. automodule:: google.cloud.asset_v1.services.asset_service
+ :members:
+ :inherited-members:
+
+
+.. automodule:: google.cloud.asset_v1.services.asset_service.pagers
+ :members:
+ :inherited-members:
diff --git a/docs/asset_v1/services.rst b/docs/asset_v1/services.rst
index 7f520451..a5ddb91f 100644
--- a/docs/asset_v1/services.rst
+++ b/docs/asset_v1/services.rst
@@ -1,6 +1,6 @@
Services for Google Cloud Asset v1 API
======================================
+.. toctree::
+ :maxdepth: 2
-.. automodule:: google.cloud.asset_v1.services.asset_service
- :members:
- :inherited-members:
+ asset_service
diff --git a/docs/asset_v1/types.rst b/docs/asset_v1/types.rst
index 750d9c16..c75a1efd 100644
--- a/docs/asset_v1/types.rst
+++ b/docs/asset_v1/types.rst
@@ -3,4 +3,5 @@ Types for Google Cloud Asset v1 API
.. automodule:: google.cloud.asset_v1.types
:members:
+ :undoc-members:
:show-inheritance:
diff --git a/docs/asset_v1p1beta1/asset_service.rst b/docs/asset_v1p1beta1/asset_service.rst
new file mode 100644
index 00000000..f88f0e38
--- /dev/null
+++ b/docs/asset_v1p1beta1/asset_service.rst
@@ -0,0 +1,11 @@
+AssetService
+------------------------------
+
+.. automodule:: google.cloud.asset_v1p1beta1.services.asset_service
+ :members:
+ :inherited-members:
+
+
+.. automodule:: google.cloud.asset_v1p1beta1.services.asset_service.pagers
+ :members:
+ :inherited-members:
diff --git a/docs/asset_v1p1beta1/services.rst b/docs/asset_v1p1beta1/services.rst
index e2f85315..2839e354 100644
--- a/docs/asset_v1p1beta1/services.rst
+++ b/docs/asset_v1p1beta1/services.rst
@@ -1,6 +1,6 @@
Services for Google Cloud Asset v1p1beta1 API
=============================================
+.. toctree::
+ :maxdepth: 2
-.. automodule:: google.cloud.asset_v1p1beta1.services.asset_service
- :members:
- :inherited-members:
+ asset_service
diff --git a/docs/asset_v1p1beta1/types.rst b/docs/asset_v1p1beta1/types.rst
index 0df91774..d0875802 100644
--- a/docs/asset_v1p1beta1/types.rst
+++ b/docs/asset_v1p1beta1/types.rst
@@ -3,4 +3,5 @@ Types for Google Cloud Asset v1p1beta1 API
.. automodule:: google.cloud.asset_v1p1beta1.types
:members:
+ :undoc-members:
:show-inheritance:
diff --git a/docs/asset_v1p2beta1/asset_service.rst b/docs/asset_v1p2beta1/asset_service.rst
new file mode 100644
index 00000000..21bc405a
--- /dev/null
+++ b/docs/asset_v1p2beta1/asset_service.rst
@@ -0,0 +1,6 @@
+AssetService
+------------------------------
+
+.. automodule:: google.cloud.asset_v1p2beta1.services.asset_service
+ :members:
+ :inherited-members:
diff --git a/docs/asset_v1p2beta1/services.rst b/docs/asset_v1p2beta1/services.rst
index 82401a22..f8ff126c 100644
--- a/docs/asset_v1p2beta1/services.rst
+++ b/docs/asset_v1p2beta1/services.rst
@@ -1,6 +1,6 @@
Services for Google Cloud Asset v1p2beta1 API
=============================================
+.. toctree::
+ :maxdepth: 2
-.. automodule:: google.cloud.asset_v1p2beta1.services.asset_service
- :members:
- :inherited-members:
+ asset_service
diff --git a/docs/asset_v1p2beta1/types.rst b/docs/asset_v1p2beta1/types.rst
index cfbf146e..b83adc35 100644
--- a/docs/asset_v1p2beta1/types.rst
+++ b/docs/asset_v1p2beta1/types.rst
@@ -3,4 +3,5 @@ Types for Google Cloud Asset v1p2beta1 API
.. automodule:: google.cloud.asset_v1p2beta1.types
:members:
+ :undoc-members:
:show-inheritance:
diff --git a/docs/asset_v1p4beta1/asset_service.rst b/docs/asset_v1p4beta1/asset_service.rst
new file mode 100644
index 00000000..e46e3c5e
--- /dev/null
+++ b/docs/asset_v1p4beta1/asset_service.rst
@@ -0,0 +1,6 @@
+AssetService
+------------------------------
+
+.. automodule:: google.cloud.asset_v1p4beta1.services.asset_service
+ :members:
+ :inherited-members:
diff --git a/docs/asset_v1p4beta1/services.rst b/docs/asset_v1p4beta1/services.rst
index 27b24147..6116177f 100644
--- a/docs/asset_v1p4beta1/services.rst
+++ b/docs/asset_v1p4beta1/services.rst
@@ -1,6 +1,6 @@
Services for Google Cloud Asset v1p4beta1 API
=============================================
+.. toctree::
+ :maxdepth: 2
-.. automodule:: google.cloud.asset_v1p4beta1.services.asset_service
- :members:
- :inherited-members:
+ asset_service
diff --git a/docs/asset_v1p4beta1/types.rst b/docs/asset_v1p4beta1/types.rst
index a91fd590..60ea41e5 100644
--- a/docs/asset_v1p4beta1/types.rst
+++ b/docs/asset_v1p4beta1/types.rst
@@ -3,4 +3,5 @@ Types for Google Cloud Asset v1p4beta1 API
.. automodule:: google.cloud.asset_v1p4beta1.types
:members:
+ :undoc-members:
:show-inheritance:
diff --git a/docs/asset_v1p5beta1/asset_service.rst b/docs/asset_v1p5beta1/asset_service.rst
new file mode 100644
index 00000000..5286192b
--- /dev/null
+++ b/docs/asset_v1p5beta1/asset_service.rst
@@ -0,0 +1,11 @@
+AssetService
+------------------------------
+
+.. automodule:: google.cloud.asset_v1p5beta1.services.asset_service
+ :members:
+ :inherited-members:
+
+
+.. automodule:: google.cloud.asset_v1p5beta1.services.asset_service.pagers
+ :members:
+ :inherited-members:
diff --git a/docs/asset_v1p5beta1/services.rst b/docs/asset_v1p5beta1/services.rst
index 09749b31..9383f20c 100644
--- a/docs/asset_v1p5beta1/services.rst
+++ b/docs/asset_v1p5beta1/services.rst
@@ -1,6 +1,6 @@
Services for Google Cloud Asset v1p5beta1 API
=============================================
+.. toctree::
+ :maxdepth: 2
-.. automodule:: google.cloud.asset_v1p5beta1.services.asset_service
- :members:
- :inherited-members:
+ asset_service
diff --git a/docs/asset_v1p5beta1/types.rst b/docs/asset_v1p5beta1/types.rst
index 0d143122..31650c9a 100644
--- a/docs/asset_v1p5beta1/types.rst
+++ b/docs/asset_v1p5beta1/types.rst
@@ -3,4 +3,5 @@ Types for Google Cloud Asset v1p5beta1 API
.. automodule:: google.cloud.asset_v1p5beta1.types
:members:
+ :undoc-members:
:show-inheritance:
diff --git a/google/cloud/asset_v1/services/asset_service/async_client.py b/google/cloud/asset_v1/services/asset_service/async_client.py
index 98c58ffa..56d7a1c2 100644
--- a/google/cloud/asset_v1/services/asset_service/async_client.py
+++ b/google/cloud/asset_v1/services/asset_service/async_client.py
@@ -78,7 +78,36 @@ class AssetServiceAsyncClient:
AssetServiceClient.parse_common_location_path
)
- from_service_account_file = AssetServiceClient.from_service_account_file
+ @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:
+ AssetServiceAsyncClient: The constructed client.
+ """
+ return AssetServiceClient.from_service_account_info.__func__(AssetServiceAsyncClient, info, *args, **kwargs) # type: ignore
+
+ @classmethod
+ def from_service_account_file(cls, filename: str, *args, **kwargs):
+ """Creates an instance of this client using the provided credentials
+ file.
+
+ Args:
+ filename (str): The path to the service account private key json
+ file.
+ args: Additional arguments to pass to the constructor.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ AssetServiceAsyncClient: The constructed client.
+ """
+ return AssetServiceClient.from_service_account_file.__func__(AssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore
+
from_service_account_json = from_service_account_file
@property
@@ -165,7 +194,7 @@ async def export_assets(
the export operation usually finishes within 5 minutes.
Args:
- request (:class:`~.asset_service.ExportAssetsRequest`):
+ request (:class:`google.cloud.asset_v1.types.ExportAssetsRequest`):
The request object. Export asset request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -175,16 +204,14 @@ async def export_assets(
sent along with the request as metadata.
Returns:
- ~.operation_async.AsyncOperation:
+ google.api_core.operation_async.AsyncOperation:
An object representing a long-running operation.
- The result type for the operation will be
- :class:``~.asset_service.ExportAssetsResponse``: The
- export asset response. This message is returned by the
- [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation]
- method in the returned
- [google.longrunning.Operation.response][google.longrunning.Operation.response]
- field.
+ The result type for the operation will be :class:`google.cloud.asset_v1.types.ExportAssetsResponse` The export asset response. This message is returned by the
+ [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation]
+ method in the returned
+ [google.longrunning.Operation.response][google.longrunning.Operation.response]
+ field.
"""
# Create or coerce a protobuf request object.
@@ -236,7 +263,7 @@ async def batch_get_assets_history(
INVALID_ARGUMENT error.
Args:
- request (:class:`~.asset_service.BatchGetAssetsHistoryRequest`):
+ request (:class:`google.cloud.asset_v1.types.BatchGetAssetsHistoryRequest`):
The request object. Batch get assets history request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -246,7 +273,7 @@ async def batch_get_assets_history(
sent along with the request as metadata.
Returns:
- ~.asset_service.BatchGetAssetsHistoryResponse:
+ google.cloud.asset_v1.types.BatchGetAssetsHistoryResponse:
Batch get assets history response.
"""
# Create or coerce a protobuf request object.
@@ -264,6 +291,7 @@ async def batch_get_assets_history(
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=DEFAULT_CLIENT_INFO,
@@ -295,7 +323,7 @@ async def create_feed(
updates.
Args:
- request (:class:`~.asset_service.CreateFeedRequest`):
+ request (:class:`google.cloud.asset_v1.types.CreateFeedRequest`):
The request object. Create asset feed request.
parent (:class:`str`):
Required. The name of the
@@ -307,6 +335,7 @@ async def create_feed(
(such as "projects/my-project-id")", or
a project number (such as
"projects/12345").
+
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -318,7 +347,7 @@ async def create_feed(
sent along with the request as metadata.
Returns:
- ~.asset_service.Feed:
+ google.cloud.asset_v1.types.Feed:
An asset feed used to export asset
updates to a destinations. An asset feed
filter controls what updates are
@@ -378,13 +407,14 @@ async def get_feed(
r"""Gets details about an asset feed.
Args:
- request (:class:`~.asset_service.GetFeedRequest`):
+ request (:class:`google.cloud.asset_v1.types.GetFeedRequest`):
The request object. Get asset feed request.
name (:class:`str`):
Required. The name of the Feed and it must be in the
format of: projects/project_number/feeds/feed_id
folders/folder_number/feeds/feed_id
organizations/organization_number/feeds/feed_id
+
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -396,7 +426,7 @@ async def get_feed(
sent along with the request as metadata.
Returns:
- ~.asset_service.Feed:
+ google.cloud.asset_v1.types.Feed:
An asset feed used to export asset
updates to a destinations. An asset feed
filter controls what updates are
@@ -435,6 +465,7 @@ async def get_feed(
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=DEFAULT_CLIENT_INFO,
@@ -465,7 +496,7 @@ async def list_feeds(
project/folder/organization.
Args:
- request (:class:`~.asset_service.ListFeedsRequest`):
+ request (:class:`google.cloud.asset_v1.types.ListFeedsRequest`):
The request object. List asset feeds request.
parent (:class:`str`):
Required. The parent
@@ -474,6 +505,7 @@ async def list_feeds(
project/folder/organization number (such
as "folders/12345")", or a project ID
(such as "projects/my-project-id").
+
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -485,7 +517,7 @@ async def list_feeds(
sent along with the request as metadata.
Returns:
- ~.asset_service.ListFeedsResponse:
+ google.cloud.asset_v1.types.ListFeedsResponse:
"""
# Create or coerce a protobuf request object.
@@ -517,6 +549,7 @@ async def list_feeds(
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=DEFAULT_CLIENT_INFO,
@@ -546,14 +579,15 @@ async def update_feed(
r"""Updates an asset feed configuration.
Args:
- request (:class:`~.asset_service.UpdateFeedRequest`):
+ request (:class:`google.cloud.asset_v1.types.UpdateFeedRequest`):
The request object. Update asset feed request.
- feed (:class:`~.asset_service.Feed`):
+ feed (:class:`google.cloud.asset_v1.types.Feed`):
Required. The new values of feed details. It must match
an existing feed and the field ``name`` must be in the
format of: projects/project_number/feeds/feed_id or
folders/folder_number/feeds/feed_id or
organizations/organization_number/feeds/feed_id.
+
This corresponds to the ``feed`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -565,7 +599,7 @@ async def update_feed(
sent along with the request as metadata.
Returns:
- ~.asset_service.Feed:
+ google.cloud.asset_v1.types.Feed:
An asset feed used to export asset
updates to a destinations. An asset feed
filter controls what updates are
@@ -627,13 +661,14 @@ async def delete_feed(
r"""Deletes an asset feed.
Args:
- request (:class:`~.asset_service.DeleteFeedRequest`):
+ request (:class:`google.cloud.asset_v1.types.DeleteFeedRequest`):
The request object.
name (:class:`str`):
Required. The name of the feed and it must be in the
format of: projects/project_number/feeds/feed_id
folders/folder_number/feeds/feed_id
organizations/organization_number/feeds/feed_id
+
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -673,6 +708,7 @@ async def delete_feed(
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=DEFAULT_CLIENT_INFO,
@@ -706,7 +742,7 @@ async def search_all_resources(
desired scope, otherwise the request will be rejected.
Args:
- request (:class:`~.asset_service.SearchAllResourcesRequest`):
+ request (:class:`google.cloud.asset_v1.types.SearchAllResourcesRequest`):
The request object. Search all resources request.
scope (:class:`str`):
Required. A scope can be a project, a folder, or an
@@ -722,6 +758,7 @@ async def search_all_resources(
- folders/{FOLDER_NUMBER} (e.g., "folders/1234567")
- organizations/{ORGANIZATION_NUMBER} (e.g.,
"organizations/123456")
+
This corresponds to the ``scope`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -765,6 +802,7 @@ async def search_all_resources(
Cloud resources that contain "Important" as a word in
any of the searchable fields and are also located in
the "us-west1" region or the "global" location.
+
This corresponds to the ``query`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -773,6 +811,7 @@ async def search_all_resources(
searches for. If empty, it will search all the
`searchable asset
types `__.
+
This corresponds to the ``asset_types`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -784,7 +823,7 @@ async def search_all_resources(
sent along with the request as metadata.
Returns:
- ~.pagers.SearchAllResourcesAsyncPager:
+ google.cloud.asset_v1.services.asset_service.pagers.SearchAllResourcesAsyncPager:
Search all resources response.
Iterating over this object will yield
results and resolve additional pages
@@ -825,6 +864,7 @@ async def search_all_resources(
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=15.0,
),
default_timeout=15.0,
client_info=DEFAULT_CLIENT_INFO,
@@ -864,7 +904,7 @@ async def search_all_iam_policies(
desired scope, otherwise the request will be rejected.
Args:
- request (:class:`~.asset_service.SearchAllIamPoliciesRequest`):
+ request (:class:`google.cloud.asset_v1.types.SearchAllIamPoliciesRequest`):
The request object. Search all IAM policies request.
scope (:class:`str`):
Required. A scope can be a project, a folder, or an
@@ -880,6 +920,7 @@ async def search_all_iam_policies(
- folders/{FOLDER_NUMBER} (e.g., "folders/1234567")
- organizations/{ORGANIZATION_NUMBER} (e.g.,
"organizations/123456")
+
This corresponds to the ``scope`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -916,6 +957,7 @@ async def search_all_iam_policies(
find IAM policy bindings that are set on resources
"instance1" or "instance2" and also specify user
"amy".
+
This corresponds to the ``query`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -927,7 +969,7 @@ async def search_all_iam_policies(
sent along with the request as metadata.
Returns:
- ~.pagers.SearchAllIamPoliciesAsyncPager:
+ google.cloud.asset_v1.services.asset_service.pagers.SearchAllIamPoliciesAsyncPager:
Search all IAM policies response.
Iterating over this object will yield
results and resolve additional pages
@@ -965,6 +1007,7 @@ async def search_all_iam_policies(
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=15.0,
),
default_timeout=15.0,
client_info=DEFAULT_CLIENT_INFO,
@@ -1000,7 +1043,7 @@ async def analyze_iam_policy(
what accesses on which resources.
Args:
- request (:class:`~.asset_service.AnalyzeIamPolicyRequest`):
+ request (:class:`google.cloud.asset_v1.types.AnalyzeIamPolicyRequest`):
The request object. A request message for
[AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy].
@@ -1011,7 +1054,7 @@ async def analyze_iam_policy(
sent along with the request as metadata.
Returns:
- ~.asset_service.AnalyzeIamPolicyResponse:
+ google.cloud.asset_v1.types.AnalyzeIamPolicyResponse:
A response message for
[AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy].
@@ -1029,6 +1072,7 @@ async def analyze_iam_policy(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(exceptions.ServiceUnavailable,),
+ deadline=300.0,
),
default_timeout=300.0,
client_info=DEFAULT_CLIENT_INFO,
@@ -1070,7 +1114,7 @@ async def analyze_iam_policy_longrunning(
to help callers to map responses to requests.
Args:
- request (:class:`~.asset_service.AnalyzeIamPolicyLongrunningRequest`):
+ request (:class:`google.cloud.asset_v1.types.AnalyzeIamPolicyLongrunningRequest`):
The request object. A request message for
[AssetService.AnalyzeIamPolicyLongrunning][google.cloud.asset.v1.AssetService.AnalyzeIamPolicyLongrunning].
@@ -1081,11 +1125,11 @@ async def analyze_iam_policy_longrunning(
sent along with the request as metadata.
Returns:
- ~.operation_async.AsyncOperation:
+ google.api_core.operation_async.AsyncOperation:
An object representing a long-running operation.
The result type for the operation will be
- :class:``~.asset_service.AnalyzeIamPolicyLongrunningResponse``:
+ :class:`google.cloud.asset_v1.types.AnalyzeIamPolicyLongrunningResponse`
A response message for
[AssetService.AnalyzeIamPolicyLongrunning][google.cloud.asset.v1.AssetService.AnalyzeIamPolicyLongrunning].
diff --git a/google/cloud/asset_v1/services/asset_service/client.py b/google/cloud/asset_v1/services/asset_service/client.py
index ef31e4a0..f65e8ba8 100644
--- a/google/cloud/asset_v1/services/asset_service/client.py
+++ b/google/cloud/asset_v1/services/asset_service/client.py
@@ -112,6 +112,22 @@ def _get_default_mtls_endpoint(api_endpoint):
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:
+ AssetServiceClient: The constructed client.
+ """
+ credentials = service_account.Credentials.from_service_account_info(info)
+ kwargs["credentials"] = credentials
+ return cls(*args, **kwargs)
+
@classmethod
def from_service_account_file(cls, filename: str, *args, **kwargs):
"""Creates an instance of this client using the provided credentials
@@ -124,7 +140,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs):
kwargs: Additional arguments to pass to the constructor.
Returns:
- {@api.name}: The constructed client.
+ AssetServiceClient: The constructed client.
"""
credentials = service_account.Credentials.from_service_account_file(filename)
kwargs["credentials"] = credentials
@@ -232,10 +248,10 @@ def __init__(
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- transport (Union[str, ~.AssetServiceTransport]): The
+ transport (Union[str, AssetServiceTransport]): The
transport to use. If set to None, a transport is chosen
automatically.
- client_options (client_options_lib.ClientOptions): Custom options for the
+ client_options (google.api_core.client_options.ClientOptions): Custom options for the
client. It won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
@@ -271,21 +287,17 @@ def __init__(
util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
)
- ssl_credentials = None
+ client_cert_source_func = None
is_mtls = False
if use_client_cert:
if client_options.client_cert_source:
- import grpc # type: ignore
-
- cert, key = client_options.client_cert_source()
- ssl_credentials = grpc.ssl_channel_credentials(
- certificate_chain=cert, private_key=key
- )
is_mtls = True
+ client_cert_source_func = client_options.client_cert_source
else:
- creds = SslCredentials()
- is_mtls = creds.is_mtls
- ssl_credentials = creds.ssl_credentials if is_mtls else None
+ is_mtls = mtls.has_default_client_cert_source()
+ client_cert_source_func = (
+ mtls.default_client_cert_source() if is_mtls else None
+ )
# Figure out which api endpoint to use.
if client_options.api_endpoint is not None:
@@ -328,7 +340,7 @@ def __init__(
credentials_file=client_options.credentials_file,
host=api_endpoint,
scopes=client_options.scopes,
- ssl_channel_credentials=ssl_credentials,
+ client_cert_source_for_mtls=client_cert_source_func,
quota_project_id=client_options.quota_project_id,
client_info=client_info,
)
@@ -356,7 +368,7 @@ def export_assets(
the export operation usually finishes within 5 minutes.
Args:
- request (:class:`~.asset_service.ExportAssetsRequest`):
+ request (google.cloud.asset_v1.types.ExportAssetsRequest):
The request object. Export asset request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -366,16 +378,14 @@ def export_assets(
sent along with the request as metadata.
Returns:
- ~.operation.Operation:
+ google.api_core.operation.Operation:
An object representing a long-running operation.
- The result type for the operation will be
- :class:``~.asset_service.ExportAssetsResponse``: The
- export asset response. This message is returned by the
- [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation]
- method in the returned
- [google.longrunning.Operation.response][google.longrunning.Operation.response]
- field.
+ The result type for the operation will be :class:`google.cloud.asset_v1.types.ExportAssetsResponse` The export asset response. This message is returned by the
+ [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation]
+ method in the returned
+ [google.longrunning.Operation.response][google.longrunning.Operation.response]
+ field.
"""
# Create or coerce a protobuf request object.
@@ -428,7 +438,7 @@ def batch_get_assets_history(
INVALID_ARGUMENT error.
Args:
- request (:class:`~.asset_service.BatchGetAssetsHistoryRequest`):
+ request (google.cloud.asset_v1.types.BatchGetAssetsHistoryRequest):
The request object. Batch get assets history request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -438,7 +448,7 @@ def batch_get_assets_history(
sent along with the request as metadata.
Returns:
- ~.asset_service.BatchGetAssetsHistoryResponse:
+ google.cloud.asset_v1.types.BatchGetAssetsHistoryResponse:
Batch get assets history response.
"""
# Create or coerce a protobuf request object.
@@ -480,9 +490,9 @@ def create_feed(
updates.
Args:
- request (:class:`~.asset_service.CreateFeedRequest`):
+ request (google.cloud.asset_v1.types.CreateFeedRequest):
The request object. Create asset feed request.
- parent (:class:`str`):
+ parent (str):
Required. The name of the
project/folder/organization where this
feed should be created in. It can only
@@ -492,6 +502,7 @@ def create_feed(
(such as "projects/my-project-id")", or
a project number (such as
"projects/12345").
+
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -503,7 +514,7 @@ def create_feed(
sent along with the request as metadata.
Returns:
- ~.asset_service.Feed:
+ google.cloud.asset_v1.types.Feed:
An asset feed used to export asset
updates to a destinations. An asset feed
filter controls what updates are
@@ -564,13 +575,14 @@ def get_feed(
r"""Gets details about an asset feed.
Args:
- request (:class:`~.asset_service.GetFeedRequest`):
+ request (google.cloud.asset_v1.types.GetFeedRequest):
The request object. Get asset feed request.
- name (:class:`str`):
+ name (str):
Required. The name of the Feed and it must be in the
format of: projects/project_number/feeds/feed_id
folders/folder_number/feeds/feed_id
organizations/organization_number/feeds/feed_id
+
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -582,7 +594,7 @@ def get_feed(
sent along with the request as metadata.
Returns:
- ~.asset_service.Feed:
+ google.cloud.asset_v1.types.Feed:
An asset feed used to export asset
updates to a destinations. An asset feed
filter controls what updates are
@@ -644,15 +656,16 @@ def list_feeds(
project/folder/organization.
Args:
- request (:class:`~.asset_service.ListFeedsRequest`):
+ request (google.cloud.asset_v1.types.ListFeedsRequest):
The request object. List asset feeds request.
- parent (:class:`str`):
+ parent (str):
Required. The parent
project/folder/organization whose feeds
are to be listed. It can only be using
project/folder/organization number (such
as "folders/12345")", or a project ID
(such as "projects/my-project-id").
+
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -664,7 +677,7 @@ def list_feeds(
sent along with the request as metadata.
Returns:
- ~.asset_service.ListFeedsResponse:
+ google.cloud.asset_v1.types.ListFeedsResponse:
"""
# Create or coerce a protobuf request object.
@@ -718,14 +731,15 @@ def update_feed(
r"""Updates an asset feed configuration.
Args:
- request (:class:`~.asset_service.UpdateFeedRequest`):
+ request (google.cloud.asset_v1.types.UpdateFeedRequest):
The request object. Update asset feed request.
- feed (:class:`~.asset_service.Feed`):
+ feed (google.cloud.asset_v1.types.Feed):
Required. The new values of feed details. It must match
an existing feed and the field ``name`` must be in the
format of: projects/project_number/feeds/feed_id or
folders/folder_number/feeds/feed_id or
organizations/organization_number/feeds/feed_id.
+
This corresponds to the ``feed`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -737,7 +751,7 @@ def update_feed(
sent along with the request as metadata.
Returns:
- ~.asset_service.Feed:
+ google.cloud.asset_v1.types.Feed:
An asset feed used to export asset
updates to a destinations. An asset feed
filter controls what updates are
@@ -800,13 +814,14 @@ def delete_feed(
r"""Deletes an asset feed.
Args:
- request (:class:`~.asset_service.DeleteFeedRequest`):
+ request (google.cloud.asset_v1.types.DeleteFeedRequest):
The request object.
- name (:class:`str`):
+ name (str):
Required. The name of the feed and it must be in the
format of: projects/project_number/feeds/feed_id
folders/folder_number/feeds/feed_id
organizations/organization_number/feeds/feed_id
+
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -872,9 +887,9 @@ def search_all_resources(
desired scope, otherwise the request will be rejected.
Args:
- request (:class:`~.asset_service.SearchAllResourcesRequest`):
+ request (google.cloud.asset_v1.types.SearchAllResourcesRequest):
The request object. Search all resources request.
- scope (:class:`str`):
+ scope (str):
Required. A scope can be a project, a folder, or an
organization. The search is limited to the resources
within the ``scope``. The caller must be granted the
@@ -888,10 +903,11 @@ def search_all_resources(
- folders/{FOLDER_NUMBER} (e.g., "folders/1234567")
- organizations/{ORGANIZATION_NUMBER} (e.g.,
"organizations/123456")
+
This corresponds to the ``scope`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- query (:class:`str`):
+ query (str):
Optional. The query statement. See `how to construct a
query `__
for more information. If not specified or empty, it will
@@ -931,14 +947,16 @@ def search_all_resources(
Cloud resources that contain "Important" as a word in
any of the searchable fields and are also located in
the "us-west1" region or the "global" location.
+
This corresponds to the ``query`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- asset_types (:class:`Sequence[str]`):
+ asset_types (Sequence[str]):
Optional. A list of asset types that this request
searches for. If empty, it will search all the
`searchable asset
types `__.
+
This corresponds to the ``asset_types`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -950,7 +968,7 @@ def search_all_resources(
sent along with the request as metadata.
Returns:
- ~.pagers.SearchAllResourcesPager:
+ google.cloud.asset_v1.services.asset_service.pagers.SearchAllResourcesPager:
Search all resources response.
Iterating over this object will yield
results and resolve additional pages
@@ -981,9 +999,8 @@ def search_all_resources(
request.scope = scope
if query is not None:
request.query = query
-
- if asset_types:
- request.asset_types.extend(asset_types)
+ if asset_types is not None:
+ request.asset_types = asset_types
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
@@ -1023,9 +1040,9 @@ def search_all_iam_policies(
desired scope, otherwise the request will be rejected.
Args:
- request (:class:`~.asset_service.SearchAllIamPoliciesRequest`):
+ request (google.cloud.asset_v1.types.SearchAllIamPoliciesRequest):
The request object. Search all IAM policies request.
- scope (:class:`str`):
+ scope (str):
Required. A scope can be a project, a folder, or an
organization. The search is limited to the IAM policies
within the ``scope``. The caller must be granted the
@@ -1039,10 +1056,11 @@ def search_all_iam_policies(
- folders/{FOLDER_NUMBER} (e.g., "folders/1234567")
- organizations/{ORGANIZATION_NUMBER} (e.g.,
"organizations/123456")
+
This corresponds to the ``scope`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- query (:class:`str`):
+ query (str):
Optional. The query statement. See `how to construct a
query `__
for more information. If not specified or empty, it will
@@ -1075,6 +1093,7 @@ def search_all_iam_policies(
find IAM policy bindings that are set on resources
"instance1" or "instance2" and also specify user
"amy".
+
This corresponds to the ``query`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -1086,7 +1105,7 @@ def search_all_iam_policies(
sent along with the request as metadata.
Returns:
- ~.pagers.SearchAllIamPoliciesPager:
+ google.cloud.asset_v1.services.asset_service.pagers.SearchAllIamPoliciesPager:
Search all IAM policies response.
Iterating over this object will yield
results and resolve additional pages
@@ -1152,7 +1171,7 @@ def analyze_iam_policy(
what accesses on which resources.
Args:
- request (:class:`~.asset_service.AnalyzeIamPolicyRequest`):
+ request (google.cloud.asset_v1.types.AnalyzeIamPolicyRequest):
The request object. A request message for
[AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy].
@@ -1163,7 +1182,7 @@ def analyze_iam_policy(
sent along with the request as metadata.
Returns:
- ~.asset_service.AnalyzeIamPolicyResponse:
+ google.cloud.asset_v1.types.AnalyzeIamPolicyResponse:
A response message for
[AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy].
@@ -1217,7 +1236,7 @@ def analyze_iam_policy_longrunning(
to help callers to map responses to requests.
Args:
- request (:class:`~.asset_service.AnalyzeIamPolicyLongrunningRequest`):
+ request (google.cloud.asset_v1.types.AnalyzeIamPolicyLongrunningRequest):
The request object. A request message for
[AssetService.AnalyzeIamPolicyLongrunning][google.cloud.asset.v1.AssetService.AnalyzeIamPolicyLongrunning].
@@ -1228,11 +1247,11 @@ def analyze_iam_policy_longrunning(
sent along with the request as metadata.
Returns:
- ~.operation.Operation:
+ google.api_core.operation.Operation:
An object representing a long-running operation.
The result type for the operation will be
- :class:``~.asset_service.AnalyzeIamPolicyLongrunningResponse``:
+ :class:`google.cloud.asset_v1.types.AnalyzeIamPolicyLongrunningResponse`
A response message for
[AssetService.AnalyzeIamPolicyLongrunning][google.cloud.asset.v1.AssetService.AnalyzeIamPolicyLongrunning].
diff --git a/google/cloud/asset_v1/services/asset_service/pagers.py b/google/cloud/asset_v1/services/asset_service/pagers.py
index 84531887..1c251731 100644
--- a/google/cloud/asset_v1/services/asset_service/pagers.py
+++ b/google/cloud/asset_v1/services/asset_service/pagers.py
@@ -15,7 +15,16 @@
# 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 google.cloud.asset_v1.types import asset_service
from google.cloud.asset_v1.types import assets
@@ -25,7 +34,7 @@ class SearchAllResourcesPager:
"""A pager for iterating through ``search_all_resources`` requests.
This class thinly wraps an initial
- :class:`~.asset_service.SearchAllResourcesResponse` object, and
+ :class:`google.cloud.asset_v1.types.SearchAllResourcesResponse` object, and
provides an ``__iter__`` method to iterate through its
``results`` field.
@@ -34,7 +43,7 @@ class SearchAllResourcesPager:
through the ``results`` field on the
corresponding responses.
- All the usual :class:`~.asset_service.SearchAllResourcesResponse`
+ All the usual :class:`google.cloud.asset_v1.types.SearchAllResourcesResponse`
attributes are available on the pager. If multiple requests are made, only
the most recent response is retained, and thus used for attribute lookup.
"""
@@ -52,9 +61,9 @@ def __init__(
Args:
method (Callable): The method that was originally called, and
which instantiated this pager.
- request (:class:`~.asset_service.SearchAllResourcesRequest`):
+ request (google.cloud.asset_v1.types.SearchAllResourcesRequest):
The initial request object.
- response (:class:`~.asset_service.SearchAllResourcesResponse`):
+ response (google.cloud.asset_v1.types.SearchAllResourcesResponse):
The initial response object.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
@@ -87,7 +96,7 @@ class SearchAllResourcesAsyncPager:
"""A pager for iterating through ``search_all_resources`` requests.
This class thinly wraps an initial
- :class:`~.asset_service.SearchAllResourcesResponse` object, and
+ :class:`google.cloud.asset_v1.types.SearchAllResourcesResponse` object, and
provides an ``__aiter__`` method to iterate through its
``results`` field.
@@ -96,7 +105,7 @@ class SearchAllResourcesAsyncPager:
through the ``results`` field on the
corresponding responses.
- All the usual :class:`~.asset_service.SearchAllResourcesResponse`
+ All the usual :class:`google.cloud.asset_v1.types.SearchAllResourcesResponse`
attributes are available on the pager. If multiple requests are made, only
the most recent response is retained, and thus used for attribute lookup.
"""
@@ -114,9 +123,9 @@ def __init__(
Args:
method (Callable): The method that was originally called, and
which instantiated this pager.
- request (:class:`~.asset_service.SearchAllResourcesRequest`):
+ request (google.cloud.asset_v1.types.SearchAllResourcesRequest):
The initial request object.
- response (:class:`~.asset_service.SearchAllResourcesResponse`):
+ response (google.cloud.asset_v1.types.SearchAllResourcesResponse):
The initial response object.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
@@ -153,7 +162,7 @@ class SearchAllIamPoliciesPager:
"""A pager for iterating through ``search_all_iam_policies`` requests.
This class thinly wraps an initial
- :class:`~.asset_service.SearchAllIamPoliciesResponse` object, and
+ :class:`google.cloud.asset_v1.types.SearchAllIamPoliciesResponse` object, and
provides an ``__iter__`` method to iterate through its
``results`` field.
@@ -162,7 +171,7 @@ class SearchAllIamPoliciesPager:
through the ``results`` field on the
corresponding responses.
- All the usual :class:`~.asset_service.SearchAllIamPoliciesResponse`
+ All the usual :class:`google.cloud.asset_v1.types.SearchAllIamPoliciesResponse`
attributes are available on the pager. If multiple requests are made, only
the most recent response is retained, and thus used for attribute lookup.
"""
@@ -180,9 +189,9 @@ def __init__(
Args:
method (Callable): The method that was originally called, and
which instantiated this pager.
- request (:class:`~.asset_service.SearchAllIamPoliciesRequest`):
+ request (google.cloud.asset_v1.types.SearchAllIamPoliciesRequest):
The initial request object.
- response (:class:`~.asset_service.SearchAllIamPoliciesResponse`):
+ response (google.cloud.asset_v1.types.SearchAllIamPoliciesResponse):
The initial response object.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
@@ -215,7 +224,7 @@ class SearchAllIamPoliciesAsyncPager:
"""A pager for iterating through ``search_all_iam_policies`` requests.
This class thinly wraps an initial
- :class:`~.asset_service.SearchAllIamPoliciesResponse` object, and
+ :class:`google.cloud.asset_v1.types.SearchAllIamPoliciesResponse` object, and
provides an ``__aiter__`` method to iterate through its
``results`` field.
@@ -224,7 +233,7 @@ class SearchAllIamPoliciesAsyncPager:
through the ``results`` field on the
corresponding responses.
- All the usual :class:`~.asset_service.SearchAllIamPoliciesResponse`
+ All the usual :class:`google.cloud.asset_v1.types.SearchAllIamPoliciesResponse`
attributes are available on the pager. If multiple requests are made, only
the most recent response is retained, and thus used for attribute lookup.
"""
@@ -242,9 +251,9 @@ def __init__(
Args:
method (Callable): The method that was originally called, and
which instantiated this pager.
- request (:class:`~.asset_service.SearchAllIamPoliciesRequest`):
+ request (google.cloud.asset_v1.types.SearchAllIamPoliciesRequest):
The initial request object.
- response (:class:`~.asset_service.SearchAllIamPoliciesResponse`):
+ response (google.cloud.asset_v1.types.SearchAllIamPoliciesResponse):
The initial response object.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
diff --git a/google/cloud/asset_v1/services/asset_service/transports/base.py b/google/cloud/asset_v1/services/asset_service/transports/base.py
index 2440e350..22201371 100644
--- a/google/cloud/asset_v1/services/asset_service/transports/base.py
+++ b/google/cloud/asset_v1/services/asset_service/transports/base.py
@@ -70,10 +70,10 @@ def __init__(
scope (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
+ 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.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
@@ -81,6 +81,9 @@ def __init__(
host += ":443"
self._host = host
+ # 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:
@@ -90,20 +93,17 @@ def __init__(
if credentials_file is not None:
credentials, _ = auth.load_credentials_from_file(
- credentials_file, scopes=scopes, quota_project_id=quota_project_id
+ credentials_file, scopes=self._scopes, quota_project_id=quota_project_id
)
elif credentials is None:
credentials, _ = auth.default(
- scopes=scopes, quota_project_id=quota_project_id
+ scopes=self._scopes, quota_project_id=quota_project_id
)
# Save the credentials.
self._credentials = credentials
- # Lifted into its own function so it can be stubbed out during tests.
- self._prep_wrapped_messages(client_info)
-
def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
@@ -119,6 +119,7 @@ def _prep_wrapped_messages(self, client_info):
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=client_info,
@@ -135,6 +136,7 @@ def _prep_wrapped_messages(self, client_info):
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=client_info,
@@ -148,6 +150,7 @@ def _prep_wrapped_messages(self, client_info):
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=client_info,
@@ -164,6 +167,7 @@ def _prep_wrapped_messages(self, client_info):
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=client_info,
@@ -177,6 +181,7 @@ def _prep_wrapped_messages(self, client_info):
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=15.0,
),
default_timeout=15.0,
client_info=client_info,
@@ -190,6 +195,7 @@ def _prep_wrapped_messages(self, client_info):
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=15.0,
),
default_timeout=15.0,
client_info=client_info,
@@ -201,6 +207,7 @@ def _prep_wrapped_messages(self, client_info):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(exceptions.ServiceUnavailable,),
+ deadline=300.0,
),
default_timeout=300.0,
client_info=client_info,
diff --git a/google/cloud/asset_v1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1/services/asset_service/transports/grpc.py
index acfa9f03..daf07dfa 100644
--- a/google/cloud/asset_v1/services/asset_service/transports/grpc.py
+++ b/google/cloud/asset_v1/services/asset_service/transports/grpc.py
@@ -60,6 +60,7 @@ def __init__(
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: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
@@ -90,6 +91,10 @@ def __init__(
``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):
@@ -104,72 +109,61 @@ 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] = {}
+ self._operations_client = None
+
+ if api_mtls_endpoint:
+ warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning)
+ if client_cert_source:
+ warnings.warn("client_cert_source is deprecated", DeprecationWarning)
if channel:
- # 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
self._ssl_channel_credentials = None
- elif api_mtls_endpoint:
- warnings.warn(
- "api_mtls_endpoint and client_cert_source are deprecated",
- DeprecationWarning,
- )
- host = (
- api_mtls_endpoint
- if ":" in api_mtls_endpoint
- else api_mtls_endpoint + ":443"
- )
+ 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
+ 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,
- options=[
- ("grpc.max_send_message_length", -1),
- ("grpc.max_receive_message_length", -1),
- ],
- )
- self._ssl_channel_credentials = ssl_credentials
- else:
- host = host if ":" in host else host + ":443"
-
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ # The base transport sets the host, credentials and scopes
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
- # create a new channel. The provided one is ignored.
+ if not self._grpc_channel:
self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
+ self._host,
+ credentials=self._credentials,
credentials_file=credentials_file,
- ssl_credentials=ssl_channel_credentials,
- scopes=scopes or self.AUTH_SCOPES,
+ scopes=self._scopes,
+ ssl_credentials=self._ssl_channel_credentials,
quota_project_id=quota_project_id,
options=[
("grpc.max_send_message_length", -1),
@@ -177,18 +171,8 @@ def __init__(
],
)
- self._stubs = {} # type: Dict[str, Callable]
- self._operations_client = None
-
- # Run the base constructor.
- super().__init__(
- host=host,
- credentials=credentials,
- credentials_file=credentials_file,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- client_info=client_info,
- )
+ # Wrap messages. This must be done after self._grpc_channel exists
+ self._prep_wrapped_messages(client_info)
@classmethod
def create_channel(
@@ -202,7 +186,7 @@ def create_channel(
) -> grpc.Channel:
"""Create and return a gRPC 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
diff --git a/google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py
index ae98bc22..2bb35c01 100644
--- a/google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py
+++ b/google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py
@@ -64,7 +64,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
@@ -104,6 +104,7 @@ def __init__(
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:
@@ -135,12 +136,16 @@ def __init__(
``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
+ 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:
@@ -149,72 +154,61 @@ 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] = {}
+ self._operations_client = None
+
+ if api_mtls_endpoint:
+ warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning)
+ if client_cert_source:
+ warnings.warn("client_cert_source is deprecated", DeprecationWarning)
if channel:
- # 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
self._ssl_channel_credentials = None
- elif api_mtls_endpoint:
- warnings.warn(
- "api_mtls_endpoint and client_cert_source are deprecated",
- DeprecationWarning,
- )
- host = (
- api_mtls_endpoint
- if ":" in api_mtls_endpoint
- else api_mtls_endpoint + ":443"
- )
+ 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
+ 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,
- options=[
- ("grpc.max_send_message_length", -1),
- ("grpc.max_receive_message_length", -1),
- ],
- )
- self._ssl_channel_credentials = ssl_credentials
- else:
- host = host if ":" in host else host + ":443"
-
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ # The base transport sets the host, credentials and scopes
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
- # create a new channel. The provided one is ignored.
+ if not self._grpc_channel:
self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
+ self._host,
+ credentials=self._credentials,
credentials_file=credentials_file,
- ssl_credentials=ssl_channel_credentials,
- scopes=scopes or self.AUTH_SCOPES,
+ scopes=self._scopes,
+ ssl_credentials=self._ssl_channel_credentials,
quota_project_id=quota_project_id,
options=[
("grpc.max_send_message_length", -1),
@@ -222,18 +216,8 @@ def __init__(
],
)
- # Run the base constructor.
- super().__init__(
- host=host,
- credentials=credentials,
- credentials_file=credentials_file,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- client_info=client_info,
- )
-
- self._stubs = {}
- self._operations_client = None
+ # Wrap messages. This must be done after self._grpc_channel exists
+ self._prep_wrapped_messages(client_info)
@property
def grpc_channel(self) -> aio.Channel:
diff --git a/google/cloud/asset_v1/types/__init__.py b/google/cloud/asset_v1/types/__init__.py
index 1dfca4b9..1143f78b 100644
--- a/google/cloud/asset_v1/types/__init__.py
+++ b/google/cloud/asset_v1/types/__init__.py
@@ -15,86 +15,86 @@
# limitations under the License.
#
-from .assets import (
- TemporalAsset,
- TimeWindow,
- Asset,
- Resource,
- ResourceSearchResult,
- IamPolicySearchResult,
- IamPolicyAnalysisState,
- IamPolicyAnalysisResult,
-)
from .asset_service import (
- ExportAssetsRequest,
- ExportAssetsResponse,
+ AnalyzeIamPolicyLongrunningRequest,
+ AnalyzeIamPolicyLongrunningResponse,
+ AnalyzeIamPolicyRequest,
+ AnalyzeIamPolicyResponse,
BatchGetAssetsHistoryRequest,
BatchGetAssetsHistoryResponse,
+ BigQueryDestination,
CreateFeedRequest,
+ DeleteFeedRequest,
+ ExportAssetsRequest,
+ ExportAssetsResponse,
+ Feed,
+ FeedOutputConfig,
+ GcsDestination,
+ GcsOutputResult,
GetFeedRequest,
+ IamPolicyAnalysisOutputConfig,
+ IamPolicyAnalysisQuery,
ListFeedsRequest,
ListFeedsResponse,
- UpdateFeedRequest,
- DeleteFeedRequest,
OutputConfig,
OutputResult,
- GcsOutputResult,
- GcsDestination,
- BigQueryDestination,
PartitionSpec,
PubsubDestination,
- FeedOutputConfig,
- Feed,
- SearchAllResourcesRequest,
- SearchAllResourcesResponse,
SearchAllIamPoliciesRequest,
SearchAllIamPoliciesResponse,
- IamPolicyAnalysisQuery,
- AnalyzeIamPolicyRequest,
- AnalyzeIamPolicyResponse,
- IamPolicyAnalysisOutputConfig,
- AnalyzeIamPolicyLongrunningRequest,
- AnalyzeIamPolicyLongrunningResponse,
+ SearchAllResourcesRequest,
+ SearchAllResourcesResponse,
+ UpdateFeedRequest,
ContentType,
)
+from .assets import (
+ Asset,
+ IamPolicyAnalysisResult,
+ IamPolicyAnalysisState,
+ IamPolicySearchResult,
+ Resource,
+ ResourceSearchResult,
+ TemporalAsset,
+ TimeWindow,
+)
__all__ = (
- "TemporalAsset",
- "TimeWindow",
- "Asset",
- "Resource",
- "ResourceSearchResult",
- "IamPolicySearchResult",
- "IamPolicyAnalysisState",
- "IamPolicyAnalysisResult",
- "ExportAssetsRequest",
- "ExportAssetsResponse",
+ "AnalyzeIamPolicyLongrunningRequest",
+ "AnalyzeIamPolicyLongrunningResponse",
+ "AnalyzeIamPolicyRequest",
+ "AnalyzeIamPolicyResponse",
"BatchGetAssetsHistoryRequest",
"BatchGetAssetsHistoryResponse",
+ "BigQueryDestination",
"CreateFeedRequest",
+ "DeleteFeedRequest",
+ "ExportAssetsRequest",
+ "ExportAssetsResponse",
+ "Feed",
+ "FeedOutputConfig",
+ "GcsDestination",
+ "GcsOutputResult",
"GetFeedRequest",
+ "IamPolicyAnalysisOutputConfig",
+ "IamPolicyAnalysisQuery",
"ListFeedsRequest",
"ListFeedsResponse",
- "UpdateFeedRequest",
- "DeleteFeedRequest",
"OutputConfig",
"OutputResult",
- "GcsOutputResult",
- "GcsDestination",
- "BigQueryDestination",
"PartitionSpec",
"PubsubDestination",
- "FeedOutputConfig",
- "Feed",
- "SearchAllResourcesRequest",
- "SearchAllResourcesResponse",
"SearchAllIamPoliciesRequest",
"SearchAllIamPoliciesResponse",
- "IamPolicyAnalysisQuery",
- "AnalyzeIamPolicyRequest",
- "AnalyzeIamPolicyResponse",
- "IamPolicyAnalysisOutputConfig",
- "AnalyzeIamPolicyLongrunningRequest",
- "AnalyzeIamPolicyLongrunningResponse",
+ "SearchAllResourcesRequest",
+ "SearchAllResourcesResponse",
+ "UpdateFeedRequest",
"ContentType",
+ "Asset",
+ "IamPolicyAnalysisResult",
+ "IamPolicyAnalysisState",
+ "IamPolicySearchResult",
+ "Resource",
+ "ResourceSearchResult",
+ "TemporalAsset",
+ "TimeWindow",
)
diff --git a/google/cloud/asset_v1/types/asset_service.py b/google/cloud/asset_v1/types/asset_service.py
index c1606428..02fca9fe 100644
--- a/google/cloud/asset_v1/types/asset_service.py
+++ b/google/cloud/asset_v1/types/asset_service.py
@@ -83,7 +83,7 @@ class ExportAssetsRequest(proto.Message):
(such as "projects/my-project-id"), or a project
number (such as "projects/12345"), or a folder
number (such as "folders/123").
- read_time (~.timestamp.Timestamp):
+ read_time (google.protobuf.timestamp_pb2.Timestamp):
Timestamp to take an asset snapshot. This can
only be set to a timestamp between the current
time and the current time minus 35 days
@@ -115,10 +115,10 @@ class ExportAssetsRequest(proto.Message):
`Introduction to Cloud Asset
Inventory `__
for all supported asset types.
- content_type (~.asset_service.ContentType):
+ content_type (google.cloud.asset_v1.types.ContentType):
Asset content type. If not specified, no
content but the asset name will be returned.
- output_config (~.asset_service.OutputConfig):
+ output_config (google.cloud.asset_v1.types.OutputConfig):
Required. Output configuration indicating
where the results will be output to.
"""
@@ -142,12 +142,12 @@ class ExportAssetsResponse(proto.Message):
field.
Attributes:
- read_time (~.timestamp.Timestamp):
+ read_time (google.protobuf.timestamp_pb2.Timestamp):
Time the snapshot was taken.
- output_config (~.asset_service.OutputConfig):
+ output_config (google.cloud.asset_v1.types.OutputConfig):
Output configuration indicating where the
results were output to.
- output_result (~.asset_service.OutputResult):
+ output_result (google.cloud.asset_v1.types.OutputResult):
Output result indicating where the assets were exported to.
For example, a set of actual Google Cloud Storage object
uris where the assets are exported to. The uris can be
@@ -183,9 +183,9 @@ class BatchGetAssetsHistoryRequest(proto.Message):
The request becomes a no-op if the asset name list is empty,
and the max size of the asset name list is 100 in one
request.
- content_type (~.asset_service.ContentType):
+ content_type (google.cloud.asset_v1.types.ContentType):
Optional. The content type.
- read_time_window (~.gca_assets.TimeWindow):
+ read_time_window (google.cloud.asset_v1.types.TimeWindow):
Optional. The time window for the asset history. Both
start_time and end_time are optional and if set, it must be
after the current time minus 35 days. If end_time is not
@@ -210,7 +210,7 @@ class BatchGetAssetsHistoryResponse(proto.Message):
r"""Batch get assets history response.
Attributes:
- assets (Sequence[~.gca_assets.TemporalAsset]):
+ assets (Sequence[google.cloud.asset_v1.types.TemporalAsset]):
A list of assets with valid time windows.
"""
@@ -236,7 +236,7 @@ class CreateFeedRequest(proto.Message):
Required. This is the client-assigned asset
feed identifier and it needs to be unique under
a specific parent project/folder/organization.
- feed (~.asset_service.Feed):
+ feed (google.cloud.asset_v1.types.Feed):
Required. The feed details. The field ``name`` must be empty
and it will be generated in the format of:
projects/project_number/feeds/feed_id
@@ -285,7 +285,7 @@ class ListFeedsResponse(proto.Message):
r"""
Attributes:
- feeds (Sequence[~.asset_service.Feed]):
+ feeds (Sequence[google.cloud.asset_v1.types.Feed]):
A list of feeds.
"""
@@ -296,13 +296,13 @@ class UpdateFeedRequest(proto.Message):
r"""Update asset feed request.
Attributes:
- feed (~.asset_service.Feed):
+ feed (google.cloud.asset_v1.types.Feed):
Required. The new values of feed details. It must match an
existing feed and the field ``name`` must be in the format
of: projects/project_number/feeds/feed_id or
folders/folder_number/feeds/feed_id or
organizations/organization_number/feeds/feed_id.
- update_mask (~.field_mask.FieldMask):
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
Required. Only updates the ``feed`` fields indicated by this
mask. The field mask must not be empty, and it must not
contain fields that are immutable or only set by the server.
@@ -331,9 +331,9 @@ class OutputConfig(proto.Message):
r"""Output configuration for export assets destination.
Attributes:
- gcs_destination (~.asset_service.GcsDestination):
+ gcs_destination (google.cloud.asset_v1.types.GcsDestination):
Destination on Cloud Storage.
- bigquery_destination (~.asset_service.BigQueryDestination):
+ bigquery_destination (google.cloud.asset_v1.types.BigQueryDestination):
Destination on BigQuery. The output table
stores the fields in asset proto as columns in
BigQuery.
@@ -352,7 +352,7 @@ class OutputResult(proto.Message):
r"""Output result of export assets.
Attributes:
- gcs_result (~.asset_service.GcsOutputResult):
+ gcs_result (google.cloud.asset_v1.types.GcsOutputResult):
Export result on Cloud Storage.
"""
@@ -420,7 +420,7 @@ class BigQueryDestination(proto.Message):
assets snapshot. If the flag is ``FALSE`` or unset and the
destination table already exists, the export call returns an
INVALID_ARGUMEMT error.
- partition_spec (~.asset_service.PartitionSpec):
+ partition_spec (google.cloud.asset_v1.types.PartitionSpec):
[partition_spec] determines whether to export to partitioned
table(s) and how to partition the data.
@@ -494,7 +494,7 @@ class PartitionSpec(proto.Message):
destination.
Attributes:
- partition_key (~.asset_service.PartitionSpec.PartitionKey):
+ partition_key (google.cloud.asset_v1.types.PartitionSpec.PartitionKey):
The partition key for BigQuery partitioned
table.
"""
@@ -529,7 +529,7 @@ class FeedOutputConfig(proto.Message):
r"""Output configuration for asset feed destination.
Attributes:
- pubsub_destination (~.asset_service.PubsubDestination):
+ pubsub_destination (google.cloud.asset_v1.types.PubsubDestination):
Destination on Pub/Sub.
"""
@@ -576,14 +576,14 @@ class Feed(proto.Message):
See `this
topic `__
for a list of all supported asset types.
- content_type (~.asset_service.ContentType):
+ content_type (google.cloud.asset_v1.types.ContentType):
Asset content type. If not specified, no
content but the asset name and type will be
returned.
- feed_output_config (~.asset_service.FeedOutputConfig):
+ feed_output_config (google.cloud.asset_v1.types.FeedOutputConfig):
Required. Feed output configuration defining
where the asset updates are published to.
- condition (~.expr.Expr):
+ condition (google.type.expr_pb2.Expr):
A condition which determines whether an asset update should
be published. If specified, an asset will be returned only
when the expression evaluates to true. When set,
@@ -717,7 +717,7 @@ class SearchAllResourcesResponse(proto.Message):
r"""Search all resources response.
Attributes:
- results (Sequence[~.gca_assets.ResourceSearchResult]):
+ results (Sequence[google.cloud.asset_v1.types.ResourceSearchResult]):
A list of Resources that match the search
query. It contains the resource standard
metadata information.
@@ -814,7 +814,7 @@ class SearchAllIamPoliciesResponse(proto.Message):
r"""Search all IAM policies response.
Attributes:
- results (Sequence[~.gca_assets.IamPolicySearchResult]):
+ results (Sequence[google.cloud.asset_v1.types.IamPolicySearchResult]):
A list of IamPolicy that match the search
query. Related information such as the
associated resource is returned along with the
@@ -856,14 +856,14 @@ class IamPolicyAnalysisQuery(proto.Message):
To know how to get folder or project id, visit
`here `__.
- resource_selector (~.asset_service.IamPolicyAnalysisQuery.ResourceSelector):
+ resource_selector (google.cloud.asset_v1.types.IamPolicyAnalysisQuery.ResourceSelector):
Optional. Specifies a resource for analysis.
- identity_selector (~.asset_service.IamPolicyAnalysisQuery.IdentitySelector):
+ identity_selector (google.cloud.asset_v1.types.IamPolicyAnalysisQuery.IdentitySelector):
Optional. Specifies an identity for analysis.
- access_selector (~.asset_service.IamPolicyAnalysisQuery.AccessSelector):
+ access_selector (google.cloud.asset_v1.types.IamPolicyAnalysisQuery.AccessSelector):
Optional. Specifies roles or permissions for
analysis. This is optional.
- options (~.asset_service.IamPolicyAnalysisQuery.Options):
+ options (google.cloud.asset_v1.types.IamPolicyAnalysisQuery.Options):
Optional. The query options.
"""
@@ -1043,9 +1043,9 @@ class AnalyzeIamPolicyRequest(proto.Message):
[AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy].
Attributes:
- analysis_query (~.asset_service.IamPolicyAnalysisQuery):
+ analysis_query (google.cloud.asset_v1.types.IamPolicyAnalysisQuery):
Required. The request query.
- execution_timeout (~.duration.Duration):
+ execution_timeout (google.protobuf.duration_pb2.Duration):
Optional. Amount of time executable has to complete. See
JSON representation of
`Duration `__.
@@ -1072,10 +1072,10 @@ class AnalyzeIamPolicyResponse(proto.Message):
[AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy].
Attributes:
- main_analysis (~.asset_service.AnalyzeIamPolicyResponse.IamPolicyAnalysis):
+ main_analysis (google.cloud.asset_v1.types.AnalyzeIamPolicyResponse.IamPolicyAnalysis):
The main analysis that matches the original
request.
- service_account_impersonation_analysis (Sequence[~.asset_service.AnalyzeIamPolicyResponse.IamPolicyAnalysis]):
+ service_account_impersonation_analysis (Sequence[google.cloud.asset_v1.types.AnalyzeIamPolicyResponse.IamPolicyAnalysis]):
The service account impersonation analysis if
[AnalyzeIamPolicyRequest.analyze_service_account_impersonation][]
is enabled.
@@ -1091,9 +1091,9 @@ class IamPolicyAnalysis(proto.Message):
r"""An analysis message to group the query and results.
Attributes:
- analysis_query (~.asset_service.IamPolicyAnalysisQuery):
+ analysis_query (google.cloud.asset_v1.types.IamPolicyAnalysisQuery):
The analysis query.
- analysis_results (Sequence[~.gca_assets.IamPolicyAnalysisResult]):
+ analysis_results (Sequence[google.cloud.asset_v1.types.IamPolicyAnalysisResult]):
A list of
[IamPolicyAnalysisResult][google.cloud.asset.v1.IamPolicyAnalysisResult]
that matches the analysis query, or empty if no result is
@@ -1102,7 +1102,7 @@ class IamPolicyAnalysis(proto.Message):
Represents whether all entries in the
[analysis_results][google.cloud.asset.v1.AnalyzeIamPolicyResponse.IamPolicyAnalysis.analysis_results]
have been fully explored to answer the query.
- non_critical_errors (Sequence[~.gca_assets.IamPolicyAnalysisState]):
+ non_critical_errors (Sequence[google.cloud.asset_v1.types.IamPolicyAnalysisState]):
A list of non-critical errors happened during
the query handling.
"""
@@ -1135,9 +1135,9 @@ class IamPolicyAnalysisOutputConfig(proto.Message):
destination.
Attributes:
- gcs_destination (~.asset_service.IamPolicyAnalysisOutputConfig.GcsDestination):
+ gcs_destination (google.cloud.asset_v1.types.IamPolicyAnalysisOutputConfig.GcsDestination):
Destination on Cloud Storage.
- bigquery_destination (~.asset_service.IamPolicyAnalysisOutputConfig.BigQueryDestination):
+ bigquery_destination (google.cloud.asset_v1.types.IamPolicyAnalysisOutputConfig.BigQueryDestination):
Destination on BigQuery.
"""
@@ -1177,7 +1177,7 @@ class BigQueryDestination(proto.Message):
[IamPolicyAnalysisResult][google.cloud.asset.v1.IamPolicyAnalysisResult].
When [partition_key] is specified, both tables will be
partitioned based on the [partition_key].
- partition_key (~.asset_service.IamPolicyAnalysisOutputConfig.BigQueryDestination.PartitionKey):
+ partition_key (google.cloud.asset_v1.types.IamPolicyAnalysisOutputConfig.BigQueryDestination.PartitionKey):
The partition key for BigQuery partitioned
table.
write_disposition (str):
@@ -1236,9 +1236,9 @@ class AnalyzeIamPolicyLongrunningRequest(proto.Message):
[AssetService.AnalyzeIamPolicyLongrunning][google.cloud.asset.v1.AssetService.AnalyzeIamPolicyLongrunning].
Attributes:
- analysis_query (~.asset_service.IamPolicyAnalysisQuery):
+ analysis_query (google.cloud.asset_v1.types.IamPolicyAnalysisQuery):
Required. The request query.
- output_config (~.asset_service.IamPolicyAnalysisOutputConfig):
+ output_config (google.cloud.asset_v1.types.IamPolicyAnalysisOutputConfig):
Required. Output configuration indicating
where the results will be output to.
"""
diff --git a/google/cloud/asset_v1/types/assets.py b/google/cloud/asset_v1/types/assets.py
index fbbac89c..43eb2482 100644
--- a/google/cloud/asset_v1/types/assets.py
+++ b/google/cloud/asset_v1/types/assets.py
@@ -50,16 +50,16 @@ class TemporalAsset(proto.Message):
window.
Attributes:
- window (~.assets.TimeWindow):
+ window (google.cloud.asset_v1.types.TimeWindow):
The time window when the asset data and state
was observed.
deleted (bool):
Whether the asset has been deleted or not.
- asset (~.assets.Asset):
+ asset (google.cloud.asset_v1.types.Asset):
An asset in Google Cloud.
- prior_asset_state (~.assets.TemporalAsset.PriorAssetState):
+ prior_asset_state (google.cloud.asset_v1.types.TemporalAsset.PriorAssetState):
State of prior_asset.
- prior_asset (~.assets.Asset):
+ prior_asset (google.cloud.asset_v1.types.Asset):
Prior copy of the asset. Populated if prior_asset_state is
PRESENT. Currently this is only set for responses in
Real-Time Feed.
@@ -88,9 +88,9 @@ class TimeWindow(proto.Message):
r"""A time window specified by its ``start_time`` and ``end_time``.
Attributes:
- start_time (~.timestamp.Timestamp):
+ start_time (google.protobuf.timestamp_pb2.Timestamp):
Start time of the time window (exclusive).
- end_time (~.timestamp.Timestamp):
+ end_time (google.protobuf.timestamp_pb2.Timestamp):
End time of the time window (inclusive). If
not specified, the current timestamp is used
instead.
@@ -112,7 +112,7 @@ class Asset(proto.Message):
for more information.
Attributes:
- update_time (~.timestamp.Timestamp):
+ update_time (google.protobuf.timestamp_pb2.Timestamp):
The last update timestamp of an asset. update_time is
updated when create/update/delete operation is performed.
name (str):
@@ -129,9 +129,9 @@ class Asset(proto.Message):
See `Supported asset
types `__
for more information.
- resource (~.assets.Resource):
+ resource (google.cloud.asset_v1.types.Resource):
A representation of the resource.
- iam_policy (~.gi_policy.Policy):
+ iam_policy (google.iam.v1.policy_pb2.Policy):
A representation of the Cloud IAM policy set on a Google
Cloud resource. There can be a maximum of one Cloud IAM
policy set on any given resource. In addition, Cloud IAM
@@ -143,21 +143,21 @@ class Asset(proto.Message):
See `this
topic `__
for more information.
- org_policy (Sequence[~.orgpolicy.Policy]):
+ org_policy (Sequence[google.cloud.orgpolicy.v1.orgpolicy_pb2.Policy]):
A representation of an `organization
policy `__.
There can be more than one organization policy with
different constraints set on a given resource.
- access_policy (~.gia_access_policy.AccessPolicy):
+ access_policy (google.identity.accesscontextmanager.v1.access_policy_pb2.AccessPolicy):
Please also refer to the `access policy user
guide `__.
- access_level (~.gia_access_level.AccessLevel):
+ access_level (google.identity.accesscontextmanager.v1.access_level_pb2.AccessLevel):
Please also refer to the `access level user
guide `__.
- service_perimeter (~.gia_service_perimeter.ServicePerimeter):
+ service_perimeter (google.identity.accesscontextmanager.v1.service_perimeter_pb2.ServicePerimeter):
Please also refer to the `service perimeter user
guide `__.
- os_inventory (~.inventory.Inventory):
+ os_inventory (google.cloud.osconfig.v1.inventory_pb2.Inventory):
A representation of runtime OS Inventory information. See
`this
topic `__
@@ -251,7 +251,7 @@ class Resource(proto.Message):
``//cloudresourcemanager.googleapis.com/projects/my_project_123``
For third-party assets, this field may be set differently.
- data (~.struct.Struct):
+ data (google.protobuf.struct_pb2.Struct):
The content of the resource, in which some
sensitive fields are removed and may not be
present.
@@ -333,7 +333,7 @@ class ResourceSearchResult(proto.Message):
- use a field query. Example: ``location:us-west*``
- use a free text query. Example: ``us-west*``
- labels (Sequence[~.assets.ResourceSearchResult.LabelsEntry]):
+ labels (Sequence[google.cloud.asset_v1.types.ResourceSearchResult.LabelsEntry]):
Labels associated with this resource. See `Labelling and
grouping GCP
resources `__
@@ -361,7 +361,7 @@ class ResourceSearchResult(proto.Message):
- use a field query. Example: ``networkTags:internal``
- use a free text query. Example: ``internal``
- additional_attributes (~.struct.Struct):
+ additional_attributes (google.protobuf.struct_pb2.Struct):
The additional searchable attributes of this resource. The
attributes may vary from one resource type to another.
Examples: ``projectId`` for Project, ``dnsName`` for DNS
@@ -433,7 +433,7 @@ class IamPolicySearchResult(proto.Message):
- specify the ``scope`` field as this project in your
search request.
- policy (~.gi_policy.Policy):
+ policy (google.iam.v1.policy_pb2.Policy):
The IAM policy directly set on the given resource. Note that
the original IAM policy can contain multiple bindings. This
only contains the bindings that match the given query. For
@@ -451,7 +451,7 @@ class IamPolicySearchResult(proto.Message):
- query by the policy contained roles' included
permissions. Example:
``policy.role.permissions:compute.instances.create``
- explanation (~.assets.IamPolicySearchResult.Explanation):
+ explanation (google.cloud.asset_v1.types.IamPolicySearchResult.Explanation):
Explanation about the IAM policy search
result. It contains additional information to
explain why the search result matches the query.
@@ -461,7 +461,7 @@ class Explanation(proto.Message):
r"""Explanation about the IAM policy search result.
Attributes:
- matched_permissions (Sequence[~.assets.IamPolicySearchResult.Explanation.MatchedPermissionsEntry]):
+ matched_permissions (Sequence[google.cloud.asset_v1.types.IamPolicySearchResult.Explanation.MatchedPermissionsEntry]):
The map from roles to their included permissions that match
the permission query (i.e., a query containing
``policy.role.permissions:``). Example: if query
@@ -506,7 +506,7 @@ class IamPolicyAnalysisState(proto.Message):
such as a resource, an identity or an access.
Attributes:
- code (~.gr_code.Code):
+ code (google.rpc.code_pb2.Code):
The Google standard error code that best describes the
state. For example:
@@ -537,14 +537,14 @@ class IamPolicyAnalysisResult(proto.Message):
of the resource to which the
[iam_binding][google.cloud.asset.v1.IamPolicyAnalysisResult.iam_binding]
policy attaches.
- iam_binding (~.gi_policy.Binding):
+ iam_binding (google.iam.v1.policy_pb2.Binding):
The Cloud IAM policy binding under analysis.
- access_control_lists (Sequence[~.assets.IamPolicyAnalysisResult.AccessControlList]):
+ access_control_lists (Sequence[google.cloud.asset_v1.types.IamPolicyAnalysisResult.AccessControlList]):
The access control lists derived from the
[iam_binding][google.cloud.asset.v1.IamPolicyAnalysisResult.iam_binding]
that match or potentially match resource and access
selectors specified in the request.
- identity_list (~.assets.IamPolicyAnalysisResult.IdentityList):
+ identity_list (google.cloud.asset_v1.types.IamPolicyAnalysisResult.IdentityList):
The identity list derived from members of the
[iam_binding][google.cloud.asset.v1.IamPolicyAnalysisResult.iam_binding]
that match or potentially match identity selector specified
@@ -562,7 +562,7 @@ class Resource(proto.Message):
full_resource_name (str):
The `full resource
name `__
- analysis_state (~.assets.IamPolicyAnalysisState):
+ analysis_state (google.cloud.asset_v1.types.IamPolicyAnalysisState):
The analysis state of this resource.
"""
@@ -580,7 +580,7 @@ class Access(proto.Message):
The role.
permission (str):
The permission.
- analysis_state (~.assets.IamPolicyAnalysisState):
+ analysis_state (google.cloud.asset_v1.types.IamPolicyAnalysisState):
The analysis state of this access.
"""
@@ -609,7 +609,7 @@ class Identity(proto.Message):
- domain:google.com
- allUsers
- etc.
- analysis_state (~.assets.IamPolicyAnalysisState):
+ analysis_state (google.cloud.asset_v1.types.IamPolicyAnalysisState):
The analysis state of this identity.
"""
@@ -658,19 +658,19 @@ class AccessControlList(proto.Message):
- AccessControlList 2: [R2, R3], [P3]
Attributes:
- resources (Sequence[~.assets.IamPolicyAnalysisResult.Resource]):
+ resources (Sequence[google.cloud.asset_v1.types.IamPolicyAnalysisResult.Resource]):
The resources that match one of the following conditions:
- The resource_selector, if it is specified in request;
- Otherwise, resources reachable from the policy attached
resource.
- accesses (Sequence[~.assets.IamPolicyAnalysisResult.Access]):
+ accesses (Sequence[google.cloud.asset_v1.types.IamPolicyAnalysisResult.Access]):
The accesses that match one of the following conditions:
- The access_selector, if it is specified in request;
- Otherwise, access specifiers reachable from the policy
binding's role.
- resource_edges (Sequence[~.assets.IamPolicyAnalysisResult.Edge]):
+ resource_edges (Sequence[google.cloud.asset_v1.types.IamPolicyAnalysisResult.Edge]):
Resource edges of the graph starting from the policy
attached resource to any descendant resources. The
[Edge.source_node][google.cloud.asset.v1.IamPolicyAnalysisResult.Edge.source_node]
@@ -697,14 +697,14 @@ class IdentityList(proto.Message):
r"""The identities and group edges.
Attributes:
- identities (Sequence[~.assets.IamPolicyAnalysisResult.Identity]):
+ identities (Sequence[google.cloud.asset_v1.types.IamPolicyAnalysisResult.Identity]):
Only the identities that match one of the following
conditions will be presented:
- The identity_selector, if it is specified in request;
- Otherwise, identities reachable from the policy binding's
members.
- group_edges (Sequence[~.assets.IamPolicyAnalysisResult.Edge]):
+ group_edges (Sequence[google.cloud.asset_v1.types.IamPolicyAnalysisResult.Edge]):
Group identity edges of the graph starting from the
binding's group members to any node of the
[identities][google.cloud.asset.v1.IamPolicyAnalysisResult.IdentityList.identities].
diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/async_client.py b/google/cloud/asset_v1p1beta1/services/asset_service/async_client.py
index 5656381e..056f1410 100644
--- a/google/cloud/asset_v1p1beta1/services/asset_service/async_client.py
+++ b/google/cloud/asset_v1p1beta1/services/asset_service/async_client.py
@@ -70,7 +70,36 @@ class AssetServiceAsyncClient:
AssetServiceClient.parse_common_location_path
)
- from_service_account_file = AssetServiceClient.from_service_account_file
+ @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:
+ AssetServiceAsyncClient: The constructed client.
+ """
+ return AssetServiceClient.from_service_account_info.__func__(AssetServiceAsyncClient, info, *args, **kwargs) # type: ignore
+
+ @classmethod
+ def from_service_account_file(cls, filename: str, *args, **kwargs):
+ """Creates an instance of this client using the provided credentials
+ file.
+
+ Args:
+ filename (str): The path to the service account private key json
+ file.
+ args: Additional arguments to pass to the constructor.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ AssetServiceAsyncClient: The constructed client.
+ """
+ return AssetServiceClient.from_service_account_file.__func__(AssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore
+
from_service_account_json = from_service_account_file
@property
@@ -154,7 +183,7 @@ async def search_all_resources(
requested scope, otherwise it will be rejected.
Args:
- request (:class:`~.asset_service.SearchAllResourcesRequest`):
+ request (:class:`google.cloud.asset_v1p1beta1.types.SearchAllResourcesRequest`):
The request object. Search all resources request.
scope (:class:`str`):
Required. The relative name of an asset. The search is
@@ -165,6 +194,7 @@ async def search_all_resources(
- Folder number(such as "folders/1234")
- Project number (such as "projects/12345")
- Project id (such as "projects/abc")
+
This corresponds to the ``scope`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -178,6 +208,7 @@ async def search_all_resources(
this request searches for. If empty, it
will search all the supported asset
types.
+
This corresponds to the ``asset_types`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -189,7 +220,7 @@ async def search_all_resources(
sent along with the request as metadata.
Returns:
- ~.pagers.SearchAllResourcesAsyncPager:
+ google.cloud.asset_v1p1beta1.services.asset_service.pagers.SearchAllResourcesAsyncPager:
Search all resources response.
Iterating over this object will yield
results and resolve additional pages
@@ -230,6 +261,7 @@ async def search_all_resources(
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=15.0,
),
default_timeout=15.0,
client_info=DEFAULT_CLIENT_INFO,
@@ -273,7 +305,7 @@ async def search_all_iam_policies(
requested scope, otherwise it will be rejected.
Args:
- request (:class:`~.asset_service.SearchAllIamPoliciesRequest`):
+ request (:class:`google.cloud.asset_v1p1beta1.types.SearchAllIamPoliciesRequest`):
The request object. Search all IAM policies request.
scope (:class:`str`):
Required. The relative name of an asset. The search is
@@ -284,6 +316,7 @@ async def search_all_iam_policies(
- Folder number(such as "folders/1234")
- Project number (such as "projects/12345")
- Project id (such as "projects/abc")
+
This corresponds to the ``scope`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -291,7 +324,8 @@ async def search_all_iam_policies(
Optional. The query statement. Examples:
- "policy:myuser@mydomain.com"
- - "policy:(myuser@mydomain.com viewer)".
+ - "policy:(myuser@mydomain.com viewer)"
+
This corresponds to the ``query`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -303,7 +337,7 @@ async def search_all_iam_policies(
sent along with the request as metadata.
Returns:
- ~.pagers.SearchAllIamPoliciesAsyncPager:
+ google.cloud.asset_v1p1beta1.services.asset_service.pagers.SearchAllIamPoliciesAsyncPager:
Search all IAM policies response.
Iterating over this object will yield
results and resolve additional pages
@@ -341,6 +375,7 @@ async def search_all_iam_policies(
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=15.0,
),
default_timeout=15.0,
client_info=DEFAULT_CLIENT_INFO,
diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/client.py b/google/cloud/asset_v1p1beta1/services/asset_service/client.py
index 416ec43a..e2a25499 100644
--- a/google/cloud/asset_v1p1beta1/services/asset_service/client.py
+++ b/google/cloud/asset_v1p1beta1/services/asset_service/client.py
@@ -109,6 +109,22 @@ def _get_default_mtls_endpoint(api_endpoint):
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:
+ AssetServiceClient: The constructed client.
+ """
+ credentials = service_account.Credentials.from_service_account_info(info)
+ kwargs["credentials"] = credentials
+ return cls(*args, **kwargs)
+
@classmethod
def from_service_account_file(cls, filename: str, *args, **kwargs):
"""Creates an instance of this client using the provided credentials
@@ -121,7 +137,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs):
kwargs: Additional arguments to pass to the constructor.
Returns:
- {@api.name}: The constructed client.
+ AssetServiceClient: The constructed client.
"""
credentials = service_account.Credentials.from_service_account_file(filename)
kwargs["credentials"] = credentials
@@ -213,10 +229,10 @@ def __init__(
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- transport (Union[str, ~.AssetServiceTransport]): The
+ transport (Union[str, AssetServiceTransport]): The
transport to use. If set to None, a transport is chosen
automatically.
- client_options (client_options_lib.ClientOptions): Custom options for the
+ client_options (google.api_core.client_options.ClientOptions): Custom options for the
client. It won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
@@ -252,21 +268,17 @@ def __init__(
util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
)
- ssl_credentials = None
+ client_cert_source_func = None
is_mtls = False
if use_client_cert:
if client_options.client_cert_source:
- import grpc # type: ignore
-
- cert, key = client_options.client_cert_source()
- ssl_credentials = grpc.ssl_channel_credentials(
- certificate_chain=cert, private_key=key
- )
is_mtls = True
+ client_cert_source_func = client_options.client_cert_source
else:
- creds = SslCredentials()
- is_mtls = creds.is_mtls
- ssl_credentials = creds.ssl_credentials if is_mtls else None
+ is_mtls = mtls.has_default_client_cert_source()
+ client_cert_source_func = (
+ mtls.default_client_cert_source() if is_mtls else None
+ )
# Figure out which api endpoint to use.
if client_options.api_endpoint is not None:
@@ -309,7 +321,7 @@ def __init__(
credentials_file=client_options.credentials_file,
host=api_endpoint,
scopes=client_options.scopes,
- ssl_channel_credentials=ssl_credentials,
+ client_cert_source_for_mtls=client_cert_source_func,
quota_project_id=client_options.quota_project_id,
client_info=client_info,
)
@@ -334,9 +346,9 @@ def search_all_resources(
requested scope, otherwise it will be rejected.
Args:
- request (:class:`~.asset_service.SearchAllResourcesRequest`):
+ request (google.cloud.asset_v1p1beta1.types.SearchAllResourcesRequest):
The request object. Search all resources request.
- scope (:class:`str`):
+ scope (str):
Required. The relative name of an asset. The search is
limited to the resources within the ``scope``. The
allowed value must be:
@@ -345,19 +357,21 @@ def search_all_resources(
- Folder number(such as "folders/1234")
- Project number (such as "projects/12345")
- Project id (such as "projects/abc")
+
This corresponds to the ``scope`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- query (:class:`str`):
+ query (str):
Optional. The query statement.
This corresponds to the ``query`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- asset_types (:class:`Sequence[str]`):
+ asset_types (Sequence[str]):
Optional. A list of asset types that
this request searches for. If empty, it
will search all the supported asset
types.
+
This corresponds to the ``asset_types`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -369,7 +383,7 @@ def search_all_resources(
sent along with the request as metadata.
Returns:
- ~.pagers.SearchAllResourcesPager:
+ google.cloud.asset_v1p1beta1.services.asset_service.pagers.SearchAllResourcesPager:
Search all resources response.
Iterating over this object will yield
results and resolve additional pages
@@ -400,9 +414,8 @@ def search_all_resources(
request.scope = scope
if query is not None:
request.query = query
-
- if asset_types:
- request.asset_types.extend(asset_types)
+ if asset_types is not None:
+ request.asset_types = asset_types
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
@@ -446,9 +459,9 @@ def search_all_iam_policies(
requested scope, otherwise it will be rejected.
Args:
- request (:class:`~.asset_service.SearchAllIamPoliciesRequest`):
+ request (google.cloud.asset_v1p1beta1.types.SearchAllIamPoliciesRequest):
The request object. Search all IAM policies request.
- scope (:class:`str`):
+ scope (str):
Required. The relative name of an asset. The search is
limited to the resources within the ``scope``. The
allowed value must be:
@@ -457,14 +470,16 @@ def search_all_iam_policies(
- Folder number(such as "folders/1234")
- Project number (such as "projects/12345")
- Project id (such as "projects/abc")
+
This corresponds to the ``scope`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- query (:class:`str`):
+ query (str):
Optional. The query statement. Examples:
- "policy:myuser@mydomain.com"
- - "policy:(myuser@mydomain.com viewer)".
+ - "policy:(myuser@mydomain.com viewer)"
+
This corresponds to the ``query`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -476,7 +491,7 @@ def search_all_iam_policies(
sent along with the request as metadata.
Returns:
- ~.pagers.SearchAllIamPoliciesPager:
+ google.cloud.asset_v1p1beta1.services.asset_service.pagers.SearchAllIamPoliciesPager:
Search all IAM policies response.
Iterating over this object will yield
results and resolve additional pages
diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/pagers.py b/google/cloud/asset_v1p1beta1/services/asset_service/pagers.py
index d41893a2..234b82b0 100644
--- a/google/cloud/asset_v1p1beta1/services/asset_service/pagers.py
+++ b/google/cloud/asset_v1p1beta1/services/asset_service/pagers.py
@@ -15,7 +15,16 @@
# 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 google.cloud.asset_v1p1beta1.types import asset_service
from google.cloud.asset_v1p1beta1.types import assets
@@ -25,7 +34,7 @@ class SearchAllResourcesPager:
"""A pager for iterating through ``search_all_resources`` requests.
This class thinly wraps an initial
- :class:`~.asset_service.SearchAllResourcesResponse` object, and
+ :class:`google.cloud.asset_v1p1beta1.types.SearchAllResourcesResponse` object, and
provides an ``__iter__`` method to iterate through its
``results`` field.
@@ -34,7 +43,7 @@ class SearchAllResourcesPager:
through the ``results`` field on the
corresponding responses.
- All the usual :class:`~.asset_service.SearchAllResourcesResponse`
+ All the usual :class:`google.cloud.asset_v1p1beta1.types.SearchAllResourcesResponse`
attributes are available on the pager. If multiple requests are made, only
the most recent response is retained, and thus used for attribute lookup.
"""
@@ -52,9 +61,9 @@ def __init__(
Args:
method (Callable): The method that was originally called, and
which instantiated this pager.
- request (:class:`~.asset_service.SearchAllResourcesRequest`):
+ request (google.cloud.asset_v1p1beta1.types.SearchAllResourcesRequest):
The initial request object.
- response (:class:`~.asset_service.SearchAllResourcesResponse`):
+ response (google.cloud.asset_v1p1beta1.types.SearchAllResourcesResponse):
The initial response object.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
@@ -87,7 +96,7 @@ class SearchAllResourcesAsyncPager:
"""A pager for iterating through ``search_all_resources`` requests.
This class thinly wraps an initial
- :class:`~.asset_service.SearchAllResourcesResponse` object, and
+ :class:`google.cloud.asset_v1p1beta1.types.SearchAllResourcesResponse` object, and
provides an ``__aiter__`` method to iterate through its
``results`` field.
@@ -96,7 +105,7 @@ class SearchAllResourcesAsyncPager:
through the ``results`` field on the
corresponding responses.
- All the usual :class:`~.asset_service.SearchAllResourcesResponse`
+ All the usual :class:`google.cloud.asset_v1p1beta1.types.SearchAllResourcesResponse`
attributes are available on the pager. If multiple requests are made, only
the most recent response is retained, and thus used for attribute lookup.
"""
@@ -114,9 +123,9 @@ def __init__(
Args:
method (Callable): The method that was originally called, and
which instantiated this pager.
- request (:class:`~.asset_service.SearchAllResourcesRequest`):
+ request (google.cloud.asset_v1p1beta1.types.SearchAllResourcesRequest):
The initial request object.
- response (:class:`~.asset_service.SearchAllResourcesResponse`):
+ response (google.cloud.asset_v1p1beta1.types.SearchAllResourcesResponse):
The initial response object.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
@@ -153,7 +162,7 @@ class SearchAllIamPoliciesPager:
"""A pager for iterating through ``search_all_iam_policies`` requests.
This class thinly wraps an initial
- :class:`~.asset_service.SearchAllIamPoliciesResponse` object, and
+ :class:`google.cloud.asset_v1p1beta1.types.SearchAllIamPoliciesResponse` object, and
provides an ``__iter__`` method to iterate through its
``results`` field.
@@ -162,7 +171,7 @@ class SearchAllIamPoliciesPager:
through the ``results`` field on the
corresponding responses.
- All the usual :class:`~.asset_service.SearchAllIamPoliciesResponse`
+ All the usual :class:`google.cloud.asset_v1p1beta1.types.SearchAllIamPoliciesResponse`
attributes are available on the pager. If multiple requests are made, only
the most recent response is retained, and thus used for attribute lookup.
"""
@@ -180,9 +189,9 @@ def __init__(
Args:
method (Callable): The method that was originally called, and
which instantiated this pager.
- request (:class:`~.asset_service.SearchAllIamPoliciesRequest`):
+ request (google.cloud.asset_v1p1beta1.types.SearchAllIamPoliciesRequest):
The initial request object.
- response (:class:`~.asset_service.SearchAllIamPoliciesResponse`):
+ response (google.cloud.asset_v1p1beta1.types.SearchAllIamPoliciesResponse):
The initial response object.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
@@ -215,7 +224,7 @@ class SearchAllIamPoliciesAsyncPager:
"""A pager for iterating through ``search_all_iam_policies`` requests.
This class thinly wraps an initial
- :class:`~.asset_service.SearchAllIamPoliciesResponse` object, and
+ :class:`google.cloud.asset_v1p1beta1.types.SearchAllIamPoliciesResponse` object, and
provides an ``__aiter__`` method to iterate through its
``results`` field.
@@ -224,7 +233,7 @@ class SearchAllIamPoliciesAsyncPager:
through the ``results`` field on the
corresponding responses.
- All the usual :class:`~.asset_service.SearchAllIamPoliciesResponse`
+ All the usual :class:`google.cloud.asset_v1p1beta1.types.SearchAllIamPoliciesResponse`
attributes are available on the pager. If multiple requests are made, only
the most recent response is retained, and thus used for attribute lookup.
"""
@@ -242,9 +251,9 @@ def __init__(
Args:
method (Callable): The method that was originally called, and
which instantiated this pager.
- request (:class:`~.asset_service.SearchAllIamPoliciesRequest`):
+ request (google.cloud.asset_v1p1beta1.types.SearchAllIamPoliciesRequest):
The initial request object.
- response (:class:`~.asset_service.SearchAllIamPoliciesResponse`):
+ response (google.cloud.asset_v1p1beta1.types.SearchAllIamPoliciesResponse):
The initial response object.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py b/google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py
index f43cae3f..ac7805cf 100644
--- a/google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py
+++ b/google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py
@@ -67,10 +67,10 @@ def __init__(
scope (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
+ 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.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
@@ -78,6 +78,9 @@ def __init__(
host += ":443"
self._host = host
+ # 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:
@@ -87,20 +90,17 @@ def __init__(
if credentials_file is not None:
credentials, _ = auth.load_credentials_from_file(
- credentials_file, scopes=scopes, quota_project_id=quota_project_id
+ credentials_file, scopes=self._scopes, quota_project_id=quota_project_id
)
elif credentials is None:
credentials, _ = auth.default(
- scopes=scopes, quota_project_id=quota_project_id
+ scopes=self._scopes, quota_project_id=quota_project_id
)
# Save the credentials.
self._credentials = credentials
- # Lifted into its own function so it can be stubbed out during tests.
- self._prep_wrapped_messages(client_info)
-
def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
@@ -113,6 +113,7 @@ def _prep_wrapped_messages(self, client_info):
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=15.0,
),
default_timeout=15.0,
client_info=client_info,
@@ -126,6 +127,7 @@ def _prep_wrapped_messages(self, client_info):
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=15.0,
),
default_timeout=15.0,
client_info=client_info,
diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py
index 1310afdb..ddeedcc9 100644
--- a/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py
+++ b/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py
@@ -57,6 +57,7 @@ def __init__(
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: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
@@ -87,6 +88,10 @@ def __init__(
``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):
@@ -101,72 +106,60 @@ 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
self._ssl_channel_credentials = None
- elif api_mtls_endpoint:
- warnings.warn(
- "api_mtls_endpoint and client_cert_source are deprecated",
- DeprecationWarning,
- )
- host = (
- api_mtls_endpoint
- if ":" in api_mtls_endpoint
- else api_mtls_endpoint + ":443"
- )
+ 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,
- options=[
- ("grpc.max_send_message_length", -1),
- ("grpc.max_receive_message_length", -1),
- ],
- )
- self._ssl_channel_credentials = ssl_credentials
- else:
- host = host if ":" in host else host + ":443"
+ 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
+ )
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ # The base transport sets the host, credentials and scopes
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
- # create a new channel. The provided one is ignored.
+ if not self._grpc_channel:
self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
+ self._host,
+ credentials=self._credentials,
credentials_file=credentials_file,
- ssl_credentials=ssl_channel_credentials,
- scopes=scopes or self.AUTH_SCOPES,
+ scopes=self._scopes,
+ ssl_credentials=self._ssl_channel_credentials,
quota_project_id=quota_project_id,
options=[
("grpc.max_send_message_length", -1),
@@ -174,17 +167,8 @@ def __init__(
],
)
- self._stubs = {} # type: Dict[str, Callable]
-
- # Run the base constructor.
- super().__init__(
- host=host,
- credentials=credentials,
- credentials_file=credentials_file,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- client_info=client_info,
- )
+ # Wrap messages. This must be done after self._grpc_channel exists
+ self._prep_wrapped_messages(client_info)
@classmethod
def create_channel(
@@ -198,7 +182,7 @@ def create_channel(
) -> grpc.Channel:
"""Create and return a gRPC 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
diff --git a/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py
index 6810dd05..fc04ac39 100644
--- a/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py
+++ b/google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py
@@ -61,7 +61,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
@@ -101,6 +101,7 @@ def __init__(
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:
@@ -132,12 +133,16 @@ def __init__(
``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
+ 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:
@@ -146,72 +151,60 @@ 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
self._ssl_channel_credentials = None
- elif api_mtls_endpoint:
- warnings.warn(
- "api_mtls_endpoint and client_cert_source are deprecated",
- DeprecationWarning,
- )
- host = (
- api_mtls_endpoint
- if ":" in api_mtls_endpoint
- else api_mtls_endpoint + ":443"
- )
+ 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,
- options=[
- ("grpc.max_send_message_length", -1),
- ("grpc.max_receive_message_length", -1),
- ],
- )
- self._ssl_channel_credentials = ssl_credentials
- else:
- host = host if ":" in host else host + ":443"
+ 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
+ )
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ # The base transport sets the host, credentials and scopes
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
- # create a new channel. The provided one is ignored.
+ if not self._grpc_channel:
self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
+ self._host,
+ credentials=self._credentials,
credentials_file=credentials_file,
- ssl_credentials=ssl_channel_credentials,
- scopes=scopes or self.AUTH_SCOPES,
+ scopes=self._scopes,
+ ssl_credentials=self._ssl_channel_credentials,
quota_project_id=quota_project_id,
options=[
("grpc.max_send_message_length", -1),
@@ -219,17 +212,8 @@ def __init__(
],
)
- # Run the base constructor.
- super().__init__(
- host=host,
- credentials=credentials,
- credentials_file=credentials_file,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- client_info=client_info,
- )
-
- self._stubs = {}
+ # Wrap messages. This must be done after self._grpc_channel exists
+ self._prep_wrapped_messages(client_info)
@property
def grpc_channel(self) -> aio.Channel:
diff --git a/google/cloud/asset_v1p1beta1/types/__init__.py b/google/cloud/asset_v1p1beta1/types/__init__.py
index a5dd1af7..47321140 100644
--- a/google/cloud/asset_v1p1beta1/types/__init__.py
+++ b/google/cloud/asset_v1p1beta1/types/__init__.py
@@ -15,24 +15,24 @@
# limitations under the License.
#
-from .assets import (
- StandardResourceMetadata,
- IamPolicySearchResult,
- Permissions,
-)
from .asset_service import (
- SearchAllResourcesRequest,
- SearchAllResourcesResponse,
SearchAllIamPoliciesRequest,
SearchAllIamPoliciesResponse,
+ SearchAllResourcesRequest,
+ SearchAllResourcesResponse,
+)
+from .assets import (
+ IamPolicySearchResult,
+ Permissions,
+ StandardResourceMetadata,
)
__all__ = (
- "StandardResourceMetadata",
- "IamPolicySearchResult",
- "Permissions",
- "SearchAllResourcesRequest",
- "SearchAllResourcesResponse",
"SearchAllIamPoliciesRequest",
"SearchAllIamPoliciesResponse",
+ "SearchAllResourcesRequest",
+ "SearchAllResourcesResponse",
+ "IamPolicySearchResult",
+ "Permissions",
+ "StandardResourceMetadata",
)
diff --git a/google/cloud/asset_v1p1beta1/types/asset_service.py b/google/cloud/asset_v1p1beta1/types/asset_service.py
index 71aa5286..b0c8459f 100644
--- a/google/cloud/asset_v1p1beta1/types/asset_service.py
+++ b/google/cloud/asset_v1p1beta1/types/asset_service.py
@@ -90,7 +90,7 @@ class SearchAllResourcesResponse(proto.Message):
r"""Search all resources response.
Attributes:
- results (Sequence[~.assets.StandardResourceMetadata]):
+ results (Sequence[google.cloud.asset_v1p1beta1.types.StandardResourceMetadata]):
A list of resource that match the search
query.
next_page_token (str):
@@ -157,7 +157,7 @@ class SearchAllIamPoliciesResponse(proto.Message):
r"""Search all IAM policies response.
Attributes:
- results (Sequence[~.assets.IamPolicySearchResult]):
+ results (Sequence[google.cloud.asset_v1p1beta1.types.IamPolicySearchResult]):
A list of IamPolicy that match the search
query. Related information such as the
associated resource is returned along with the
diff --git a/google/cloud/asset_v1p1beta1/types/assets.py b/google/cloud/asset_v1p1beta1/types/assets.py
index d53fa624..9fa19903 100644
--- a/google/cloud/asset_v1p1beta1/types/assets.py
+++ b/google/cloud/asset_v1p1beta1/types/assets.py
@@ -57,7 +57,7 @@ class StandardResourceMetadata(proto.Message):
location (str):
Location can be "global", regional like "us-
ast1", or zonal like "us-west1-b".
- labels (Sequence[~.assets.StandardResourceMetadata.LabelsEntry]):
+ labels (Sequence[google.cloud.asset_v1p1beta1.types.StandardResourceMetadata.LabelsEntry]):
Labels associated with this resource. See `Labelling and
grouping GCP
resources `__
@@ -104,7 +104,7 @@ class IamPolicySearchResult(proto.Message):
bucket), the project field will indicate the project that
contains the resource. If an IAM policy is set on a folder
or orgnization, the project field will be empty.
- policy (~.giv_policy.Policy):
+ policy (google.iam.v1.policy_pb2.Policy):
The IAM policy directly set on the given
resource. Note that the original IAM policy can
contain multiple bindings. This only contains
@@ -112,7 +112,7 @@ class IamPolicySearchResult(proto.Message):
queries that don't contain a constrain on
policies (e.g. an empty query), this contains
all the bindings.
- explanation (~.assets.IamPolicySearchResult.Explanation):
+ explanation (google.cloud.asset_v1p1beta1.types.IamPolicySearchResult.Explanation):
Explanation about the IAM policy search
result. It contains additional information to
explain why the search result matches the query.
@@ -122,7 +122,7 @@ class Explanation(proto.Message):
r"""Explanation about the IAM policy search result.
Attributes:
- matched_permissions (Sequence[~.assets.IamPolicySearchResult.Explanation.MatchedPermissionsEntry]):
+ matched_permissions (Sequence[google.cloud.asset_v1p1beta1.types.IamPolicySearchResult.Explanation.MatchedPermissionsEntry]):
The map from roles to their included permission matching the
permission query (e.g. containing
``policy.role.permissions:``). A sample role string:
diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/async_client.py b/google/cloud/asset_v1p2beta1/services/asset_service/async_client.py
index 11230e08..b6ab2109 100644
--- a/google/cloud/asset_v1p2beta1/services/asset_service/async_client.py
+++ b/google/cloud/asset_v1p2beta1/services/asset_service/async_client.py
@@ -71,7 +71,36 @@ class AssetServiceAsyncClient:
AssetServiceClient.parse_common_location_path
)
- from_service_account_file = AssetServiceClient.from_service_account_file
+ @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:
+ AssetServiceAsyncClient: The constructed client.
+ """
+ return AssetServiceClient.from_service_account_info.__func__(AssetServiceAsyncClient, info, *args, **kwargs) # type: ignore
+
+ @classmethod
+ def from_service_account_file(cls, filename: str, *args, **kwargs):
+ """Creates an instance of this client using the provided credentials
+ file.
+
+ Args:
+ filename (str): The path to the service account private key json
+ file.
+ args: Additional arguments to pass to the constructor.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ AssetServiceAsyncClient: The constructed client.
+ """
+ return AssetServiceClient.from_service_account_file.__func__(AssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore
+
from_service_account_json = from_service_account_file
@property
@@ -149,7 +178,7 @@ async def create_feed(
updates.
Args:
- request (:class:`~.asset_service.CreateFeedRequest`):
+ request (:class:`google.cloud.asset_v1p2beta1.types.CreateFeedRequest`):
The request object. Create asset feed request.
parent (:class:`str`):
Required. The name of the
@@ -161,6 +190,7 @@ async def create_feed(
(such as "projects/my-project-id")", or
a project number (such as
"projects/12345").
+
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -172,7 +202,7 @@ async def create_feed(
sent along with the request as metadata.
Returns:
- ~.asset_service.Feed:
+ google.cloud.asset_v1p2beta1.types.Feed:
An asset feed used to export asset
updates to a destinations. An asset feed
filter controls what updates are
@@ -232,13 +262,14 @@ async def get_feed(
r"""Gets details about an asset feed.
Args:
- request (:class:`~.asset_service.GetFeedRequest`):
+ request (:class:`google.cloud.asset_v1p2beta1.types.GetFeedRequest`):
The request object. Get asset feed request.
name (:class:`str`):
Required. The name of the Feed and it must be in the
format of: projects/project_number/feeds/feed_id
folders/folder_number/feeds/feed_id
organizations/organization_number/feeds/feed_id
+
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -250,7 +281,7 @@ async def get_feed(
sent along with the request as metadata.
Returns:
- ~.asset_service.Feed:
+ google.cloud.asset_v1p2beta1.types.Feed:
An asset feed used to export asset
updates to a destinations. An asset feed
filter controls what updates are
@@ -289,6 +320,7 @@ async def get_feed(
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=DEFAULT_CLIENT_INFO,
@@ -319,7 +351,7 @@ async def list_feeds(
project/folder/organization.
Args:
- request (:class:`~.asset_service.ListFeedsRequest`):
+ request (:class:`google.cloud.asset_v1p2beta1.types.ListFeedsRequest`):
The request object. List asset feeds request.
parent (:class:`str`):
Required. The parent
@@ -328,6 +360,7 @@ async def list_feeds(
project/folder/organization number (such
as "folders/12345")", or a project ID
(such as "projects/my-project-id").
+
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -339,7 +372,7 @@ async def list_feeds(
sent along with the request as metadata.
Returns:
- ~.asset_service.ListFeedsResponse:
+ google.cloud.asset_v1p2beta1.types.ListFeedsResponse:
"""
# Create or coerce a protobuf request object.
@@ -371,6 +404,7 @@ async def list_feeds(
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=DEFAULT_CLIENT_INFO,
@@ -400,14 +434,15 @@ async def update_feed(
r"""Updates an asset feed configuration.
Args:
- request (:class:`~.asset_service.UpdateFeedRequest`):
+ request (:class:`google.cloud.asset_v1p2beta1.types.UpdateFeedRequest`):
The request object. Update asset feed request.
- feed (:class:`~.asset_service.Feed`):
+ feed (:class:`google.cloud.asset_v1p2beta1.types.Feed`):
Required. The new values of feed details. It must match
an existing feed and the field ``name`` must be in the
format of: projects/project_number/feeds/feed_id or
folders/folder_number/feeds/feed_id or
organizations/organization_number/feeds/feed_id.
+
This corresponds to the ``feed`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -419,7 +454,7 @@ async def update_feed(
sent along with the request as metadata.
Returns:
- ~.asset_service.Feed:
+ google.cloud.asset_v1p2beta1.types.Feed:
An asset feed used to export asset
updates to a destinations. An asset feed
filter controls what updates are
@@ -481,13 +516,14 @@ async def delete_feed(
r"""Deletes an asset feed.
Args:
- request (:class:`~.asset_service.DeleteFeedRequest`):
+ request (:class:`google.cloud.asset_v1p2beta1.types.DeleteFeedRequest`):
The request object.
name (:class:`str`):
Required. The name of the feed and it must be in the
format of: projects/project_number/feeds/feed_id
folders/folder_number/feeds/feed_id
organizations/organization_number/feeds/feed_id
+
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -527,6 +563,7 @@ async def delete_feed(
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=DEFAULT_CLIENT_INFO,
diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/client.py b/google/cloud/asset_v1p2beta1/services/asset_service/client.py
index 36f37947..a2ddcef1 100644
--- a/google/cloud/asset_v1p2beta1/services/asset_service/client.py
+++ b/google/cloud/asset_v1p2beta1/services/asset_service/client.py
@@ -107,6 +107,22 @@ def _get_default_mtls_endpoint(api_endpoint):
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:
+ AssetServiceClient: The constructed client.
+ """
+ credentials = service_account.Credentials.from_service_account_info(info)
+ kwargs["credentials"] = credentials
+ return cls(*args, **kwargs)
+
@classmethod
def from_service_account_file(cls, filename: str, *args, **kwargs):
"""Creates an instance of this client using the provided credentials
@@ -119,7 +135,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs):
kwargs: Additional arguments to pass to the constructor.
Returns:
- {@api.name}: The constructed client.
+ AssetServiceClient: The constructed client.
"""
credentials = service_account.Credentials.from_service_account_file(filename)
kwargs["credentials"] = credentials
@@ -222,10 +238,10 @@ def __init__(
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- transport (Union[str, ~.AssetServiceTransport]): The
+ transport (Union[str, AssetServiceTransport]): The
transport to use. If set to None, a transport is chosen
automatically.
- client_options (client_options_lib.ClientOptions): Custom options for the
+ client_options (google.api_core.client_options.ClientOptions): Custom options for the
client. It won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
@@ -261,21 +277,17 @@ def __init__(
util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
)
- ssl_credentials = None
+ client_cert_source_func = None
is_mtls = False
if use_client_cert:
if client_options.client_cert_source:
- import grpc # type: ignore
-
- cert, key = client_options.client_cert_source()
- ssl_credentials = grpc.ssl_channel_credentials(
- certificate_chain=cert, private_key=key
- )
is_mtls = True
+ client_cert_source_func = client_options.client_cert_source
else:
- creds = SslCredentials()
- is_mtls = creds.is_mtls
- ssl_credentials = creds.ssl_credentials if is_mtls else None
+ is_mtls = mtls.has_default_client_cert_source()
+ client_cert_source_func = (
+ mtls.default_client_cert_source() if is_mtls else None
+ )
# Figure out which api endpoint to use.
if client_options.api_endpoint is not None:
@@ -318,7 +330,7 @@ def __init__(
credentials_file=client_options.credentials_file,
host=api_endpoint,
scopes=client_options.scopes,
- ssl_channel_credentials=ssl_credentials,
+ client_cert_source_for_mtls=client_cert_source_func,
quota_project_id=client_options.quota_project_id,
client_info=client_info,
)
@@ -337,9 +349,9 @@ def create_feed(
updates.
Args:
- request (:class:`~.asset_service.CreateFeedRequest`):
+ request (google.cloud.asset_v1p2beta1.types.CreateFeedRequest):
The request object. Create asset feed request.
- parent (:class:`str`):
+ parent (str):
Required. The name of the
project/folder/organization where this
feed should be created in. It can only
@@ -349,6 +361,7 @@ def create_feed(
(such as "projects/my-project-id")", or
a project number (such as
"projects/12345").
+
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -360,7 +373,7 @@ def create_feed(
sent along with the request as metadata.
Returns:
- ~.asset_service.Feed:
+ google.cloud.asset_v1p2beta1.types.Feed:
An asset feed used to export asset
updates to a destinations. An asset feed
filter controls what updates are
@@ -421,13 +434,14 @@ def get_feed(
r"""Gets details about an asset feed.
Args:
- request (:class:`~.asset_service.GetFeedRequest`):
+ request (google.cloud.asset_v1p2beta1.types.GetFeedRequest):
The request object. Get asset feed request.
- name (:class:`str`):
+ name (str):
Required. The name of the Feed and it must be in the
format of: projects/project_number/feeds/feed_id
folders/folder_number/feeds/feed_id
organizations/organization_number/feeds/feed_id
+
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -439,7 +453,7 @@ def get_feed(
sent along with the request as metadata.
Returns:
- ~.asset_service.Feed:
+ google.cloud.asset_v1p2beta1.types.Feed:
An asset feed used to export asset
updates to a destinations. An asset feed
filter controls what updates are
@@ -501,15 +515,16 @@ def list_feeds(
project/folder/organization.
Args:
- request (:class:`~.asset_service.ListFeedsRequest`):
+ request (google.cloud.asset_v1p2beta1.types.ListFeedsRequest):
The request object. List asset feeds request.
- parent (:class:`str`):
+ parent (str):
Required. The parent
project/folder/organization whose feeds
are to be listed. It can only be using
project/folder/organization number (such
as "folders/12345")", or a project ID
(such as "projects/my-project-id").
+
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -521,7 +536,7 @@ def list_feeds(
sent along with the request as metadata.
Returns:
- ~.asset_service.ListFeedsResponse:
+ google.cloud.asset_v1p2beta1.types.ListFeedsResponse:
"""
# Create or coerce a protobuf request object.
@@ -575,14 +590,15 @@ def update_feed(
r"""Updates an asset feed configuration.
Args:
- request (:class:`~.asset_service.UpdateFeedRequest`):
+ request (google.cloud.asset_v1p2beta1.types.UpdateFeedRequest):
The request object. Update asset feed request.
- feed (:class:`~.asset_service.Feed`):
+ feed (google.cloud.asset_v1p2beta1.types.Feed):
Required. The new values of feed details. It must match
an existing feed and the field ``name`` must be in the
format of: projects/project_number/feeds/feed_id or
folders/folder_number/feeds/feed_id or
organizations/organization_number/feeds/feed_id.
+
This corresponds to the ``feed`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -594,7 +610,7 @@ def update_feed(
sent along with the request as metadata.
Returns:
- ~.asset_service.Feed:
+ google.cloud.asset_v1p2beta1.types.Feed:
An asset feed used to export asset
updates to a destinations. An asset feed
filter controls what updates are
@@ -657,13 +673,14 @@ def delete_feed(
r"""Deletes an asset feed.
Args:
- request (:class:`~.asset_service.DeleteFeedRequest`):
+ request (google.cloud.asset_v1p2beta1.types.DeleteFeedRequest):
The request object.
- name (:class:`str`):
+ name (str):
Required. The name of the feed and it must be in the
format of: projects/project_number/feeds/feed_id
folders/folder_number/feeds/feed_id
organizations/organization_number/feeds/feed_id
+
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/transports/base.py b/google/cloud/asset_v1p2beta1/services/asset_service/transports/base.py
index 7f9a2afa..fae4c7be 100644
--- a/google/cloud/asset_v1p2beta1/services/asset_service/transports/base.py
+++ b/google/cloud/asset_v1p2beta1/services/asset_service/transports/base.py
@@ -68,10 +68,10 @@ def __init__(
scope (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
+ 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.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
@@ -79,6 +79,9 @@ def __init__(
host += ":443"
self._host = host
+ # 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:
@@ -88,20 +91,17 @@ def __init__(
if credentials_file is not None:
credentials, _ = auth.load_credentials_from_file(
- credentials_file, scopes=scopes, quota_project_id=quota_project_id
+ credentials_file, scopes=self._scopes, quota_project_id=quota_project_id
)
elif credentials is None:
credentials, _ = auth.default(
- scopes=scopes, quota_project_id=quota_project_id
+ scopes=self._scopes, quota_project_id=quota_project_id
)
# Save the credentials.
self._credentials = credentials
- # Lifted into its own function so it can be stubbed out during tests.
- self._prep_wrapped_messages(client_info)
-
def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
@@ -117,6 +117,7 @@ def _prep_wrapped_messages(self, client_info):
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=client_info,
@@ -130,6 +131,7 @@ def _prep_wrapped_messages(self, client_info):
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=client_info,
@@ -146,6 +148,7 @@ def _prep_wrapped_messages(self, client_info):
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=client_info,
diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py
index e30ae165..70d3ab33 100644
--- a/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py
+++ b/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py
@@ -58,6 +58,7 @@ def __init__(
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: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
@@ -88,6 +89,10 @@ def __init__(
``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):
@@ -102,72 +107,60 @@ 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
self._ssl_channel_credentials = None
- elif api_mtls_endpoint:
- warnings.warn(
- "api_mtls_endpoint and client_cert_source are deprecated",
- DeprecationWarning,
- )
- host = (
- api_mtls_endpoint
- if ":" in api_mtls_endpoint
- else api_mtls_endpoint + ":443"
- )
+ 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,
- options=[
- ("grpc.max_send_message_length", -1),
- ("grpc.max_receive_message_length", -1),
- ],
- )
- self._ssl_channel_credentials = ssl_credentials
- else:
- host = host if ":" in host else host + ":443"
+ 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
+ )
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ # The base transport sets the host, credentials and scopes
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
- # create a new channel. The provided one is ignored.
+ if not self._grpc_channel:
self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
+ self._host,
+ credentials=self._credentials,
credentials_file=credentials_file,
- ssl_credentials=ssl_channel_credentials,
- scopes=scopes or self.AUTH_SCOPES,
+ scopes=self._scopes,
+ ssl_credentials=self._ssl_channel_credentials,
quota_project_id=quota_project_id,
options=[
("grpc.max_send_message_length", -1),
@@ -175,17 +168,8 @@ def __init__(
],
)
- self._stubs = {} # type: Dict[str, Callable]
-
- # Run the base constructor.
- super().__init__(
- host=host,
- credentials=credentials,
- credentials_file=credentials_file,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- client_info=client_info,
- )
+ # Wrap messages. This must be done after self._grpc_channel exists
+ self._prep_wrapped_messages(client_info)
@classmethod
def create_channel(
@@ -199,7 +183,7 @@ def create_channel(
) -> grpc.Channel:
"""Create and return a gRPC 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
diff --git a/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py
index 59b54443..275c68d3 100644
--- a/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py
+++ b/google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py
@@ -62,7 +62,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
@@ -102,6 +102,7 @@ def __init__(
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:
@@ -133,12 +134,16 @@ def __init__(
``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
+ 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:
@@ -147,72 +152,60 @@ 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
self._ssl_channel_credentials = None
- elif api_mtls_endpoint:
- warnings.warn(
- "api_mtls_endpoint and client_cert_source are deprecated",
- DeprecationWarning,
- )
- host = (
- api_mtls_endpoint
- if ":" in api_mtls_endpoint
- else api_mtls_endpoint + ":443"
- )
+ 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,
- options=[
- ("grpc.max_send_message_length", -1),
- ("grpc.max_receive_message_length", -1),
- ],
- )
- self._ssl_channel_credentials = ssl_credentials
- else:
- host = host if ":" in host else host + ":443"
+ 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
+ )
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ # The base transport sets the host, credentials and scopes
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
- # create a new channel. The provided one is ignored.
+ if not self._grpc_channel:
self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
+ self._host,
+ credentials=self._credentials,
credentials_file=credentials_file,
- ssl_credentials=ssl_channel_credentials,
- scopes=scopes or self.AUTH_SCOPES,
+ scopes=self._scopes,
+ ssl_credentials=self._ssl_channel_credentials,
quota_project_id=quota_project_id,
options=[
("grpc.max_send_message_length", -1),
@@ -220,17 +213,8 @@ def __init__(
],
)
- # Run the base constructor.
- super().__init__(
- host=host,
- credentials=credentials,
- credentials_file=credentials_file,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- client_info=client_info,
- )
-
- self._stubs = {}
+ # Wrap messages. This must be done after self._grpc_channel exists
+ self._prep_wrapped_messages(client_info)
@property
def grpc_channel(self) -> aio.Channel:
diff --git a/google/cloud/asset_v1p2beta1/types/__init__.py b/google/cloud/asset_v1p2beta1/types/__init__.py
index 7c5b86e3..0976221c 100644
--- a/google/cloud/asset_v1p2beta1/types/__init__.py
+++ b/google/cloud/asset_v1p2beta1/types/__init__.py
@@ -15,42 +15,42 @@
# limitations under the License.
#
-from .assets import (
- TemporalAsset,
- TimeWindow,
- Asset,
- Resource,
-)
from .asset_service import (
CreateFeedRequest,
+ DeleteFeedRequest,
+ Feed,
+ FeedOutputConfig,
+ GcsDestination,
GetFeedRequest,
ListFeedsRequest,
ListFeedsResponse,
- UpdateFeedRequest,
- DeleteFeedRequest,
OutputConfig,
- GcsDestination,
PubsubDestination,
- FeedOutputConfig,
- Feed,
+ UpdateFeedRequest,
ContentType,
)
+from .assets import (
+ Asset,
+ Resource,
+ TemporalAsset,
+ TimeWindow,
+)
__all__ = (
- "TemporalAsset",
- "TimeWindow",
- "Asset",
- "Resource",
"CreateFeedRequest",
+ "DeleteFeedRequest",
+ "Feed",
+ "FeedOutputConfig",
+ "GcsDestination",
"GetFeedRequest",
"ListFeedsRequest",
"ListFeedsResponse",
- "UpdateFeedRequest",
- "DeleteFeedRequest",
"OutputConfig",
- "GcsDestination",
"PubsubDestination",
- "FeedOutputConfig",
- "Feed",
+ "UpdateFeedRequest",
"ContentType",
+ "Asset",
+ "Resource",
+ "TemporalAsset",
+ "TimeWindow",
)
diff --git a/google/cloud/asset_v1p2beta1/types/asset_service.py b/google/cloud/asset_v1p2beta1/types/asset_service.py
index 43aa2f1a..74a242ca 100644
--- a/google/cloud/asset_v1p2beta1/types/asset_service.py
+++ b/google/cloud/asset_v1p2beta1/types/asset_service.py
@@ -64,7 +64,7 @@ class CreateFeedRequest(proto.Message):
Required. This is the client-assigned asset
feed identifier and it needs to be unique under
a specific parent project/folder/organization.
- feed (~.asset_service.Feed):
+ feed (google.cloud.asset_v1p2beta1.types.Feed):
Required. The feed details. The field ``name`` must be empty
and it will be generated in the format of:
projects/project_number/feeds/feed_id
@@ -113,7 +113,7 @@ class ListFeedsResponse(proto.Message):
r"""
Attributes:
- feeds (Sequence[~.asset_service.Feed]):
+ feeds (Sequence[google.cloud.asset_v1p2beta1.types.Feed]):
A list of feeds.
"""
@@ -124,13 +124,13 @@ class UpdateFeedRequest(proto.Message):
r"""Update asset feed request.
Attributes:
- feed (~.asset_service.Feed):
+ feed (google.cloud.asset_v1p2beta1.types.Feed):
Required. The new values of feed details. It must match an
existing feed and the field ``name`` must be in the format
of: projects/project_number/feeds/feed_id or
folders/folder_number/feeds/feed_id or
organizations/organization_number/feeds/feed_id.
- update_mask (~.field_mask.FieldMask):
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
Required. Only updates the ``feed`` fields indicated by this
mask. The field mask must not be empty, and it must not
contain fields that are immutable or only set by the server.
@@ -159,7 +159,7 @@ class OutputConfig(proto.Message):
r"""Output configuration for export assets destination.
Attributes:
- gcs_destination (~.asset_service.GcsDestination):
+ gcs_destination (google.cloud.asset_v1p2beta1.types.GcsDestination):
Destination on Cloud Storage.
"""
@@ -200,7 +200,7 @@ class FeedOutputConfig(proto.Message):
r"""Output configuration for asset feed destination.
Attributes:
- pubsub_destination (~.asset_service.PubsubDestination):
+ pubsub_destination (google.cloud.asset_v1p2beta1.types.PubsubDestination):
Destination on Cloud Pubsub.
"""
@@ -246,11 +246,11 @@ class Feed(proto.Message):
Asset
Inventory `__
for all supported asset types.
- content_type (~.asset_service.ContentType):
+ content_type (google.cloud.asset_v1p2beta1.types.ContentType):
Asset content type. If not specified, no
content but the asset name and type will be
returned.
- feed_output_config (~.asset_service.FeedOutputConfig):
+ feed_output_config (google.cloud.asset_v1p2beta1.types.FeedOutputConfig):
Required. Feed output configuration defining
where the asset updates are published to.
"""
diff --git a/google/cloud/asset_v1p2beta1/types/assets.py b/google/cloud/asset_v1p2beta1/types/assets.py
index 84f260f3..aa225389 100644
--- a/google/cloud/asset_v1p2beta1/types/assets.py
+++ b/google/cloud/asset_v1p2beta1/types/assets.py
@@ -35,12 +35,12 @@ class TemporalAsset(proto.Message):
it.
Attributes:
- window (~.assets.TimeWindow):
+ window (google.cloud.asset_v1p2beta1.types.TimeWindow):
The time window when the asset data and state
was observed.
deleted (bool):
If the asset is deleted or not.
- asset (~.assets.Asset):
+ asset (google.cloud.asset_v1p2beta1.types.Asset):
Asset.
"""
@@ -55,9 +55,9 @@ class TimeWindow(proto.Message):
r"""A time window of (start_time, end_time].
Attributes:
- start_time (~.timestamp.Timestamp):
+ start_time (google.protobuf.timestamp_pb2.Timestamp):
Start time of the time window (exclusive).
- end_time (~.timestamp.Timestamp):
+ end_time (google.protobuf.timestamp_pb2.Timestamp):
End time of the time window (inclusive).
Current timestamp if not specified.
"""
@@ -81,9 +81,9 @@ class Asset(proto.Message):
asset_type (str):
Type of the asset. Example:
"compute.googleapis.com/Disk".
- resource (~.assets.Resource):
+ resource (google.cloud.asset_v1p2beta1.types.Resource):
Representation of the resource.
- iam_policy (~.policy.Policy):
+ iam_policy (google.iam.v1.policy_pb2.Policy):
Representation of the actual Cloud IAM policy
set on a cloud resource. For each resource,
there must be at most one Cloud IAM policy set
@@ -147,7 +147,7 @@ class Resource(proto.Message):
``"//cloudresourcemanager.googleapis.com/projects/my_project_123"``.
For third-party assets, it is up to the users to define.
- data (~.struct.Struct):
+ data (google.protobuf.struct_pb2.Struct):
The content of the resource, in which some
sensitive fields are scrubbed away and may not
be present.
diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/async_client.py b/google/cloud/asset_v1p4beta1/services/asset_service/async_client.py
index f3880182..d4267794 100644
--- a/google/cloud/asset_v1p4beta1/services/asset_service/async_client.py
+++ b/google/cloud/asset_v1p4beta1/services/asset_service/async_client.py
@@ -71,7 +71,36 @@ class AssetServiceAsyncClient:
AssetServiceClient.parse_common_location_path
)
- from_service_account_file = AssetServiceClient.from_service_account_file
+ @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:
+ AssetServiceAsyncClient: The constructed client.
+ """
+ return AssetServiceClient.from_service_account_info.__func__(AssetServiceAsyncClient, info, *args, **kwargs) # type: ignore
+
+ @classmethod
+ def from_service_account_file(cls, filename: str, *args, **kwargs):
+ """Creates an instance of this client using the provided credentials
+ file.
+
+ Args:
+ filename (str): The path to the service account private key json
+ file.
+ args: Additional arguments to pass to the constructor.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ AssetServiceAsyncClient: The constructed client.
+ """
+ return AssetServiceClient.from_service_account_file.__func__(AssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore
+
from_service_account_json = from_service_account_file
@property
@@ -149,7 +178,7 @@ async def analyze_iam_policy(
matching the request.
Args:
- request (:class:`~.asset_service.AnalyzeIamPolicyRequest`):
+ request (:class:`google.cloud.asset_v1p4beta1.types.AnalyzeIamPolicyRequest`):
The request object. A request message for
[AssetService.AnalyzeIamPolicy][google.cloud.asset.v1p4beta1.AssetService.AnalyzeIamPolicy].
@@ -160,7 +189,7 @@ async def analyze_iam_policy(
sent along with the request as metadata.
Returns:
- ~.asset_service.AnalyzeIamPolicyResponse:
+ google.cloud.asset_v1p4beta1.types.AnalyzeIamPolicyResponse:
A response message for
[AssetService.AnalyzeIamPolicy][google.cloud.asset.v1p4beta1.AssetService.AnalyzeIamPolicy].
@@ -178,6 +207,7 @@ async def analyze_iam_policy(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(exceptions.ServiceUnavailable,),
+ deadline=300.0,
),
default_timeout=300.0,
client_info=DEFAULT_CLIENT_INFO,
@@ -212,7 +242,7 @@ async def export_iam_policy_analysis(
the request to help callers to map responses to requests.
Args:
- request (:class:`~.asset_service.ExportIamPolicyAnalysisRequest`):
+ request (:class:`google.cloud.asset_v1p4beta1.types.ExportIamPolicyAnalysisRequest`):
The request object. A request message for
[AssetService.ExportIamPolicyAnalysis][google.cloud.asset.v1p4beta1.AssetService.ExportIamPolicyAnalysis].
@@ -223,16 +253,13 @@ async def export_iam_policy_analysis(
sent along with the request as metadata.
Returns:
- ~.operation_async.AsyncOperation:
+ google.api_core.operation_async.AsyncOperation:
An object representing a long-running operation.
- The result type for the operation will be
- :class:``~.asset_service.ExportIamPolicyAnalysisResponse``:
- The export IAM policy analysis response. This message is
- returned by the
- [google.longrunning.Operations.GetOperation][] method in
- the returned [google.longrunning.Operation.response][]
- field.
+ The result type for the operation will be :class:`google.cloud.asset_v1p4beta1.types.ExportIamPolicyAnalysisResponse` The export IAM policy analysis response. This message is returned by the
+ [google.longrunning.Operations.GetOperation][] method
+ in the returned
+ [google.longrunning.Operation.response][] field.
"""
# Create or coerce a protobuf request object.
diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/client.py b/google/cloud/asset_v1p4beta1/services/asset_service/client.py
index 7fe58691..f5a39adb 100644
--- a/google/cloud/asset_v1p4beta1/services/asset_service/client.py
+++ b/google/cloud/asset_v1p4beta1/services/asset_service/client.py
@@ -110,6 +110,22 @@ def _get_default_mtls_endpoint(api_endpoint):
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:
+ AssetServiceClient: The constructed client.
+ """
+ credentials = service_account.Credentials.from_service_account_info(info)
+ kwargs["credentials"] = credentials
+ return cls(*args, **kwargs)
+
@classmethod
def from_service_account_file(cls, filename: str, *args, **kwargs):
"""Creates an instance of this client using the provided credentials
@@ -122,7 +138,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs):
kwargs: Additional arguments to pass to the constructor.
Returns:
- {@api.name}: The constructed client.
+ AssetServiceClient: The constructed client.
"""
credentials = service_account.Credentials.from_service_account_file(filename)
kwargs["credentials"] = credentials
@@ -214,10 +230,10 @@ def __init__(
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- transport (Union[str, ~.AssetServiceTransport]): The
+ transport (Union[str, AssetServiceTransport]): The
transport to use. If set to None, a transport is chosen
automatically.
- client_options (client_options_lib.ClientOptions): Custom options for the
+ client_options (google.api_core.client_options.ClientOptions): Custom options for the
client. It won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
@@ -253,21 +269,17 @@ def __init__(
util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
)
- ssl_credentials = None
+ client_cert_source_func = None
is_mtls = False
if use_client_cert:
if client_options.client_cert_source:
- import grpc # type: ignore
-
- cert, key = client_options.client_cert_source()
- ssl_credentials = grpc.ssl_channel_credentials(
- certificate_chain=cert, private_key=key
- )
is_mtls = True
+ client_cert_source_func = client_options.client_cert_source
else:
- creds = SslCredentials()
- is_mtls = creds.is_mtls
- ssl_credentials = creds.ssl_credentials if is_mtls else None
+ is_mtls = mtls.has_default_client_cert_source()
+ client_cert_source_func = (
+ mtls.default_client_cert_source() if is_mtls else None
+ )
# Figure out which api endpoint to use.
if client_options.api_endpoint is not None:
@@ -310,7 +322,7 @@ def __init__(
credentials_file=client_options.credentials_file,
host=api_endpoint,
scopes=client_options.scopes,
- ssl_channel_credentials=ssl_credentials,
+ client_cert_source_for_mtls=client_cert_source_func,
quota_project_id=client_options.quota_project_id,
client_info=client_info,
)
@@ -329,7 +341,7 @@ def analyze_iam_policy(
matching the request.
Args:
- request (:class:`~.asset_service.AnalyzeIamPolicyRequest`):
+ request (google.cloud.asset_v1p4beta1.types.AnalyzeIamPolicyRequest):
The request object. A request message for
[AssetService.AnalyzeIamPolicy][google.cloud.asset.v1p4beta1.AssetService.AnalyzeIamPolicy].
@@ -340,7 +352,7 @@ def analyze_iam_policy(
sent along with the request as metadata.
Returns:
- ~.asset_service.AnalyzeIamPolicyResponse:
+ google.cloud.asset_v1p4beta1.types.AnalyzeIamPolicyResponse:
A response message for
[AssetService.AnalyzeIamPolicy][google.cloud.asset.v1p4beta1.AssetService.AnalyzeIamPolicy].
@@ -387,7 +399,7 @@ def export_iam_policy_analysis(
the request to help callers to map responses to requests.
Args:
- request (:class:`~.asset_service.ExportIamPolicyAnalysisRequest`):
+ request (google.cloud.asset_v1p4beta1.types.ExportIamPolicyAnalysisRequest):
The request object. A request message for
[AssetService.ExportIamPolicyAnalysis][google.cloud.asset.v1p4beta1.AssetService.ExportIamPolicyAnalysis].
@@ -398,16 +410,13 @@ def export_iam_policy_analysis(
sent along with the request as metadata.
Returns:
- ~.operation.Operation:
+ google.api_core.operation.Operation:
An object representing a long-running operation.
- The result type for the operation will be
- :class:``~.asset_service.ExportIamPolicyAnalysisResponse``:
- The export IAM policy analysis response. This message is
- returned by the
- [google.longrunning.Operations.GetOperation][] method in
- the returned [google.longrunning.Operation.response][]
- field.
+ The result type for the operation will be :class:`google.cloud.asset_v1p4beta1.types.ExportIamPolicyAnalysisResponse` The export IAM policy analysis response. This message is returned by the
+ [google.longrunning.Operations.GetOperation][] method
+ in the returned
+ [google.longrunning.Operation.response][] field.
"""
# Create or coerce a protobuf request object.
diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/transports/base.py b/google/cloud/asset_v1p4beta1/services/asset_service/transports/base.py
index 190c8cda..8702f39f 100644
--- a/google/cloud/asset_v1p4beta1/services/asset_service/transports/base.py
+++ b/google/cloud/asset_v1p4beta1/services/asset_service/transports/base.py
@@ -69,10 +69,10 @@ def __init__(
scope (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
+ 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.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
@@ -80,6 +80,9 @@ def __init__(
host += ":443"
self._host = host
+ # 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:
@@ -89,20 +92,17 @@ def __init__(
if credentials_file is not None:
credentials, _ = auth.load_credentials_from_file(
- credentials_file, scopes=scopes, quota_project_id=quota_project_id
+ credentials_file, scopes=self._scopes, quota_project_id=quota_project_id
)
elif credentials is None:
credentials, _ = auth.default(
- scopes=scopes, quota_project_id=quota_project_id
+ scopes=self._scopes, quota_project_id=quota_project_id
)
# Save the credentials.
self._credentials = credentials
- # Lifted into its own function so it can be stubbed out during tests.
- self._prep_wrapped_messages(client_info)
-
def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
@@ -113,6 +113,7 @@ def _prep_wrapped_messages(self, client_info):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(exceptions.ServiceUnavailable,),
+ deadline=300.0,
),
default_timeout=300.0,
client_info=client_info,
diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py
index 301fb6f9..7d2c0298 100644
--- a/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py
+++ b/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py
@@ -59,6 +59,7 @@ def __init__(
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: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
@@ -89,6 +90,10 @@ def __init__(
``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):
@@ -103,72 +108,61 @@ 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] = {}
+ self._operations_client = None
+
+ if api_mtls_endpoint:
+ warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning)
+ if client_cert_source:
+ warnings.warn("client_cert_source is deprecated", DeprecationWarning)
if channel:
- # 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
self._ssl_channel_credentials = None
- elif api_mtls_endpoint:
- warnings.warn(
- "api_mtls_endpoint and client_cert_source are deprecated",
- DeprecationWarning,
- )
- host = (
- api_mtls_endpoint
- if ":" in api_mtls_endpoint
- else api_mtls_endpoint + ":443"
- )
+ 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
+ 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,
- options=[
- ("grpc.max_send_message_length", -1),
- ("grpc.max_receive_message_length", -1),
- ],
- )
- self._ssl_channel_credentials = ssl_credentials
- else:
- host = host if ":" in host else host + ":443"
-
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ # The base transport sets the host, credentials and scopes
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
- # create a new channel. The provided one is ignored.
+ if not self._grpc_channel:
self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
+ self._host,
+ credentials=self._credentials,
credentials_file=credentials_file,
- ssl_credentials=ssl_channel_credentials,
- scopes=scopes or self.AUTH_SCOPES,
+ scopes=self._scopes,
+ ssl_credentials=self._ssl_channel_credentials,
quota_project_id=quota_project_id,
options=[
("grpc.max_send_message_length", -1),
@@ -176,18 +170,8 @@ def __init__(
],
)
- self._stubs = {} # type: Dict[str, Callable]
- self._operations_client = None
-
- # Run the base constructor.
- super().__init__(
- host=host,
- credentials=credentials,
- credentials_file=credentials_file,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- client_info=client_info,
- )
+ # Wrap messages. This must be done after self._grpc_channel exists
+ self._prep_wrapped_messages(client_info)
@classmethod
def create_channel(
@@ -201,7 +185,7 @@ def create_channel(
) -> grpc.Channel:
"""Create and return a gRPC 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
diff --git a/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py
index 52f74e7d..f61d756b 100644
--- a/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py
+++ b/google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py
@@ -63,7 +63,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
@@ -103,6 +103,7 @@ def __init__(
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:
@@ -134,12 +135,16 @@ def __init__(
``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
+ 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:
@@ -148,72 +153,61 @@ 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] = {}
+ self._operations_client = None
+
+ if api_mtls_endpoint:
+ warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning)
+ if client_cert_source:
+ warnings.warn("client_cert_source is deprecated", DeprecationWarning)
if channel:
- # 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
self._ssl_channel_credentials = None
- elif api_mtls_endpoint:
- warnings.warn(
- "api_mtls_endpoint and client_cert_source are deprecated",
- DeprecationWarning,
- )
- host = (
- api_mtls_endpoint
- if ":" in api_mtls_endpoint
- else api_mtls_endpoint + ":443"
- )
+ 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
+ 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,
- options=[
- ("grpc.max_send_message_length", -1),
- ("grpc.max_receive_message_length", -1),
- ],
- )
- self._ssl_channel_credentials = ssl_credentials
- else:
- host = host if ":" in host else host + ":443"
-
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ # The base transport sets the host, credentials and scopes
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
- # create a new channel. The provided one is ignored.
+ if not self._grpc_channel:
self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
+ self._host,
+ credentials=self._credentials,
credentials_file=credentials_file,
- ssl_credentials=ssl_channel_credentials,
- scopes=scopes or self.AUTH_SCOPES,
+ scopes=self._scopes,
+ ssl_credentials=self._ssl_channel_credentials,
quota_project_id=quota_project_id,
options=[
("grpc.max_send_message_length", -1),
@@ -221,18 +215,8 @@ def __init__(
],
)
- # Run the base constructor.
- super().__init__(
- host=host,
- credentials=credentials,
- credentials_file=credentials_file,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- client_info=client_info,
- )
-
- self._stubs = {}
- self._operations_client = None
+ # Wrap messages. This must be done after self._grpc_channel exists
+ self._prep_wrapped_messages(client_info)
@property
def grpc_channel(self) -> aio.Channel:
diff --git a/google/cloud/asset_v1p4beta1/types/__init__.py b/google/cloud/asset_v1p4beta1/types/__init__.py
index 72b608ca..cfe344dd 100644
--- a/google/cloud/asset_v1p4beta1/types/__init__.py
+++ b/google/cloud/asset_v1p4beta1/types/__init__.py
@@ -15,22 +15,22 @@
# limitations under the License.
#
-from .assets import IamPolicyAnalysisResult
from .asset_service import (
- IamPolicyAnalysisQuery,
AnalyzeIamPolicyRequest,
AnalyzeIamPolicyResponse,
- IamPolicyAnalysisOutputConfig,
ExportIamPolicyAnalysisRequest,
ExportIamPolicyAnalysisResponse,
+ IamPolicyAnalysisOutputConfig,
+ IamPolicyAnalysisQuery,
)
+from .assets import IamPolicyAnalysisResult
__all__ = (
- "IamPolicyAnalysisResult",
- "IamPolicyAnalysisQuery",
"AnalyzeIamPolicyRequest",
"AnalyzeIamPolicyResponse",
- "IamPolicyAnalysisOutputConfig",
"ExportIamPolicyAnalysisRequest",
"ExportIamPolicyAnalysisResponse",
+ "IamPolicyAnalysisOutputConfig",
+ "IamPolicyAnalysisQuery",
+ "IamPolicyAnalysisResult",
)
diff --git a/google/cloud/asset_v1p4beta1/types/asset_service.py b/google/cloud/asset_v1p4beta1/types/asset_service.py
index 2f9285b2..67002613 100644
--- a/google/cloud/asset_v1p4beta1/types/asset_service.py
+++ b/google/cloud/asset_v1p4beta1/types/asset_service.py
@@ -46,13 +46,13 @@ class IamPolicyAnalysisQuery(proto.Message):
organization number (such as
"organizations/123") or a folder number (such as
"folders/123").
- resource_selector (~.asset_service.IamPolicyAnalysisQuery.ResourceSelector):
+ resource_selector (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisQuery.ResourceSelector):
Optional. Specifies a resource for analysis.
Leaving it empty means ANY.
- identity_selector (~.asset_service.IamPolicyAnalysisQuery.IdentitySelector):
+ identity_selector (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisQuery.IdentitySelector):
Optional. Specifies an identity for analysis.
Leaving it empty means ANY.
- access_selector (~.asset_service.IamPolicyAnalysisQuery.AccessSelector):
+ access_selector (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisQuery.AccessSelector):
Optional. Specifies roles or permissions for
analysis. Leaving it empty means ANY.
"""
@@ -122,9 +122,9 @@ class AnalyzeIamPolicyRequest(proto.Message):
[AssetService.AnalyzeIamPolicy][google.cloud.asset.v1p4beta1.AssetService.AnalyzeIamPolicy].
Attributes:
- analysis_query (~.asset_service.IamPolicyAnalysisQuery):
+ analysis_query (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisQuery):
Required. The request query.
- options (~.asset_service.AnalyzeIamPolicyRequest.Options):
+ options (google.cloud.asset_v1p4beta1.types.AnalyzeIamPolicyRequest.Options):
Optional. The request options.
"""
@@ -200,7 +200,7 @@ class Options(proto.Message):
[AnalyzeIamPolicyResponse.service_account_impersonation_analysis][google.cloud.asset.v1p4beta1.AnalyzeIamPolicyResponse.service_account_impersonation_analysis].
Default is false.
- execution_timeout (~.duration.Duration):
+ execution_timeout (google.protobuf.duration_pb2.Duration):
Optional. Amount of time executable has to complete. See
JSON representation of
`Duration `__.
@@ -243,10 +243,10 @@ class AnalyzeIamPolicyResponse(proto.Message):
[AssetService.AnalyzeIamPolicy][google.cloud.asset.v1p4beta1.AssetService.AnalyzeIamPolicy].
Attributes:
- main_analysis (~.asset_service.AnalyzeIamPolicyResponse.IamPolicyAnalysis):
+ main_analysis (google.cloud.asset_v1p4beta1.types.AnalyzeIamPolicyResponse.IamPolicyAnalysis):
The main analysis that matches the original
request.
- service_account_impersonation_analysis (Sequence[~.asset_service.AnalyzeIamPolicyResponse.IamPolicyAnalysis]):
+ service_account_impersonation_analysis (Sequence[google.cloud.asset_v1p4beta1.types.AnalyzeIamPolicyResponse.IamPolicyAnalysis]):
The service account impersonation analysis if
[AnalyzeIamPolicyRequest.analyze_service_account_impersonation][]
is enabled.
@@ -256,7 +256,7 @@ class AnalyzeIamPolicyResponse(proto.Message):
and
[service_account_impersonation_analysis][google.cloud.asset.v1p4beta1.AnalyzeIamPolicyResponse.service_account_impersonation_analysis]
have been fully explored to answer the query in the request.
- non_critical_errors (Sequence[~.assets.IamPolicyAnalysisResult.AnalysisState]):
+ non_critical_errors (Sequence[google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisResult.AnalysisState]):
A list of non-critical errors happened during the request
handling to explain why ``fully_explored`` is false, or
empty if no error happened.
@@ -266,9 +266,9 @@ class IamPolicyAnalysis(proto.Message):
r"""An analysis message to group the query and results.
Attributes:
- analysis_query (~.asset_service.IamPolicyAnalysisQuery):
+ analysis_query (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisQuery):
The analysis query.
- analysis_results (Sequence[~.assets.IamPolicyAnalysisResult]):
+ analysis_results (Sequence[google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisResult]):
A list of
[IamPolicyAnalysisResult][google.cloud.asset.v1p4beta1.IamPolicyAnalysisResult]
that matches the analysis query, or empty if no result is
@@ -307,7 +307,7 @@ class IamPolicyAnalysisOutputConfig(proto.Message):
destination.
Attributes:
- gcs_destination (~.asset_service.IamPolicyAnalysisOutputConfig.GcsDestination):
+ gcs_destination (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisOutputConfig.GcsDestination):
Destination on Cloud Storage.
"""
@@ -336,11 +336,11 @@ class ExportIamPolicyAnalysisRequest(proto.Message):
[AssetService.ExportIamPolicyAnalysis][google.cloud.asset.v1p4beta1.AssetService.ExportIamPolicyAnalysis].
Attributes:
- analysis_query (~.asset_service.IamPolicyAnalysisQuery):
+ analysis_query (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisQuery):
Required. The request query.
- options (~.asset_service.ExportIamPolicyAnalysisRequest.Options):
+ options (google.cloud.asset_v1p4beta1.types.ExportIamPolicyAnalysisRequest.Options):
Optional. The request options.
- output_config (~.asset_service.IamPolicyAnalysisOutputConfig):
+ output_config (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisOutputConfig):
Required. Output configuration indicating
where the results will be output to.
"""
@@ -447,7 +447,7 @@ class ExportIamPolicyAnalysisResponse(proto.Message):
returned [google.longrunning.Operation.response][] field.
Attributes:
- output_config (~.asset_service.IamPolicyAnalysisOutputConfig):
+ output_config (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisOutputConfig):
Output configuration indicating where the
results were output to.
"""
diff --git a/google/cloud/asset_v1p4beta1/types/assets.py b/google/cloud/asset_v1p4beta1/types/assets.py
index af57f224..92609db9 100644
--- a/google/cloud/asset_v1p4beta1/types/assets.py
+++ b/google/cloud/asset_v1p4beta1/types/assets.py
@@ -36,14 +36,14 @@ class IamPolicyAnalysisResult(proto.Message):
The full name of the resource to which the
[iam_binding][google.cloud.asset.v1p4beta1.IamPolicyAnalysisResult.iam_binding]
policy attaches.
- iam_binding (~.policy.Binding):
+ iam_binding (google.iam.v1.policy_pb2.Binding):
The Cloud IAM policy binding under analysis.
- access_control_lists (Sequence[~.assets.IamPolicyAnalysisResult.AccessControlList]):
+ access_control_lists (Sequence[google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisResult.AccessControlList]):
The access control lists derived from the
[iam_binding][google.cloud.asset.v1p4beta1.IamPolicyAnalysisResult.iam_binding]
that match or potentially match resource and access
selectors specified in the request.
- identity_list (~.assets.IamPolicyAnalysisResult.IdentityList):
+ identity_list (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisResult.IdentityList):
The identity list derived from members of the
[iam_binding][google.cloud.asset.v1p4beta1.IamPolicyAnalysisResult.iam_binding]
that match or potentially match identity selector specified
@@ -60,7 +60,7 @@ class AnalysisState(proto.Message):
non-critical errors in the response.
Attributes:
- code (~.gr_code.Code):
+ code (google.rpc.code_pb2.Code):
The Google standard error code that best describes the
state. For example:
@@ -85,7 +85,7 @@ class Resource(proto.Message):
full_resource_name (str):
The `full resource
name `__.
- analysis_state (~.assets.IamPolicyAnalysisResult.AnalysisState):
+ analysis_state (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisResult.AnalysisState):
The analysis state of this resource node.
"""
@@ -103,7 +103,7 @@ class Access(proto.Message):
The role.
permission (str):
The permission.
- analysis_state (~.assets.IamPolicyAnalysisResult.AnalysisState):
+ analysis_state (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisResult.AnalysisState):
The analysis state of this access node.
"""
@@ -146,7 +146,7 @@ class Identity(proto.Message):
- domain:google.com
- allUsers
- etc.
- analysis_state (~.assets.IamPolicyAnalysisResult.AnalysisState):
+ analysis_state (google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisResult.AnalysisState):
The analysis state of this identity node.
"""
@@ -177,19 +177,19 @@ class AccessControlList(proto.Message):
- AccessControlList 2: [R2, R3], [P3]
Attributes:
- resources (Sequence[~.assets.IamPolicyAnalysisResult.Resource]):
+ resources (Sequence[google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisResult.Resource]):
The resources that match one of the following conditions:
- The resource_selector, if it is specified in request;
- Otherwise, resources reachable from the policy attached
resource.
- accesses (Sequence[~.assets.IamPolicyAnalysisResult.Access]):
+ accesses (Sequence[google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisResult.Access]):
The accesses that match one of the following conditions:
- The access_selector, if it is specified in request;
- Otherwise, access specifiers reachable from the policy
binding's role.
- resource_edges (Sequence[~.assets.IamPolicyAnalysisResult.Edge]):
+ resource_edges (Sequence[google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisResult.Edge]):
Resource edges of the graph starting from the policy
attached resource to any descendant resources. The
[Edge.source_node][google.cloud.asset.v1p4beta1.IamPolicyAnalysisResult.Edge.source_node]
@@ -216,14 +216,14 @@ class IdentityList(proto.Message):
r"""
Attributes:
- identities (Sequence[~.assets.IamPolicyAnalysisResult.Identity]):
+ identities (Sequence[google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisResult.Identity]):
Only the identities that match one of the following
conditions will be presented:
- The identity_selector, if it is specified in request;
- Otherwise, identities reachable from the policy binding's
members.
- group_edges (Sequence[~.assets.IamPolicyAnalysisResult.Edge]):
+ group_edges (Sequence[google.cloud.asset_v1p4beta1.types.IamPolicyAnalysisResult.Edge]):
Group identity edges of the graph starting from the
binding's group members to any node of the
[identities][google.cloud.asset.v1p4beta1.IamPolicyAnalysisResult.IdentityList.identities].
diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/async_client.py b/google/cloud/asset_v1p5beta1/services/asset_service/async_client.py
index e5d56974..537bc1d9 100644
--- a/google/cloud/asset_v1p5beta1/services/asset_service/async_client.py
+++ b/google/cloud/asset_v1p5beta1/services/asset_service/async_client.py
@@ -72,7 +72,36 @@ class AssetServiceAsyncClient:
AssetServiceClient.parse_common_location_path
)
- from_service_account_file = AssetServiceClient.from_service_account_file
+ @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:
+ AssetServiceAsyncClient: The constructed client.
+ """
+ return AssetServiceClient.from_service_account_info.__func__(AssetServiceAsyncClient, info, *args, **kwargs) # type: ignore
+
+ @classmethod
+ def from_service_account_file(cls, filename: str, *args, **kwargs):
+ """Creates an instance of this client using the provided credentials
+ file.
+
+ Args:
+ filename (str): The path to the service account private key json
+ file.
+ args: Additional arguments to pass to the constructor.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ AssetServiceAsyncClient: The constructed client.
+ """
+ return AssetServiceClient.from_service_account_file.__func__(AssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore
+
from_service_account_json = from_service_account_file
@property
@@ -148,7 +177,7 @@ async def list_assets(
paged results in response.
Args:
- request (:class:`~.asset_service.ListAssetsRequest`):
+ request (:class:`google.cloud.asset_v1p5beta1.types.ListAssetsRequest`):
The request object. ListAssets request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -158,7 +187,7 @@ async def list_assets(
sent along with the request as metadata.
Returns:
- ~.pagers.ListAssetsAsyncPager:
+ google.cloud.asset_v1p5beta1.services.asset_service.pagers.ListAssetsAsyncPager:
ListAssets response.
Iterating over this object will yield
results and resolve additional pages
@@ -180,6 +209,7 @@ async def list_assets(
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=DEFAULT_CLIENT_INFO,
diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/client.py b/google/cloud/asset_v1p5beta1/services/asset_service/client.py
index 0ba04274..64df55d1 100644
--- a/google/cloud/asset_v1p5beta1/services/asset_service/client.py
+++ b/google/cloud/asset_v1p5beta1/services/asset_service/client.py
@@ -109,6 +109,22 @@ def _get_default_mtls_endpoint(api_endpoint):
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:
+ AssetServiceClient: The constructed client.
+ """
+ credentials = service_account.Credentials.from_service_account_info(info)
+ kwargs["credentials"] = credentials
+ return cls(*args, **kwargs)
+
@classmethod
def from_service_account_file(cls, filename: str, *args, **kwargs):
"""Creates an instance of this client using the provided credentials
@@ -121,7 +137,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs):
kwargs: Additional arguments to pass to the constructor.
Returns:
- {@api.name}: The constructed client.
+ AssetServiceClient: The constructed client.
"""
credentials = service_account.Credentials.from_service_account_file(filename)
kwargs["credentials"] = credentials
@@ -218,10 +234,10 @@ def __init__(
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- transport (Union[str, ~.AssetServiceTransport]): The
+ transport (Union[str, AssetServiceTransport]): The
transport to use. If set to None, a transport is chosen
automatically.
- client_options (client_options_lib.ClientOptions): Custom options for the
+ client_options (google.api_core.client_options.ClientOptions): Custom options for the
client. It won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
@@ -257,21 +273,17 @@ def __init__(
util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
)
- ssl_credentials = None
+ client_cert_source_func = None
is_mtls = False
if use_client_cert:
if client_options.client_cert_source:
- import grpc # type: ignore
-
- cert, key = client_options.client_cert_source()
- ssl_credentials = grpc.ssl_channel_credentials(
- certificate_chain=cert, private_key=key
- )
is_mtls = True
+ client_cert_source_func = client_options.client_cert_source
else:
- creds = SslCredentials()
- is_mtls = creds.is_mtls
- ssl_credentials = creds.ssl_credentials if is_mtls else None
+ is_mtls = mtls.has_default_client_cert_source()
+ client_cert_source_func = (
+ mtls.default_client_cert_source() if is_mtls else None
+ )
# Figure out which api endpoint to use.
if client_options.api_endpoint is not None:
@@ -314,7 +326,7 @@ def __init__(
credentials_file=client_options.credentials_file,
host=api_endpoint,
scopes=client_options.scopes,
- ssl_channel_credentials=ssl_credentials,
+ client_cert_source_for_mtls=client_cert_source_func,
quota_project_id=client_options.quota_project_id,
client_info=client_info,
)
@@ -331,7 +343,7 @@ def list_assets(
paged results in response.
Args:
- request (:class:`~.asset_service.ListAssetsRequest`):
+ request (google.cloud.asset_v1p5beta1.types.ListAssetsRequest):
The request object. ListAssets request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -341,7 +353,7 @@ def list_assets(
sent along with the request as metadata.
Returns:
- ~.pagers.ListAssetsPager:
+ google.cloud.asset_v1p5beta1.services.asset_service.pagers.ListAssetsPager:
ListAssets response.
Iterating over this object will yield
results and resolve additional pages
diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/pagers.py b/google/cloud/asset_v1p5beta1/services/asset_service/pagers.py
index 734e01aa..ddd260b9 100644
--- a/google/cloud/asset_v1p5beta1/services/asset_service/pagers.py
+++ b/google/cloud/asset_v1p5beta1/services/asset_service/pagers.py
@@ -15,7 +15,16 @@
# 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 google.cloud.asset_v1p5beta1.types import asset_service
from google.cloud.asset_v1p5beta1.types import assets
@@ -25,7 +34,7 @@ class ListAssetsPager:
"""A pager for iterating through ``list_assets`` requests.
This class thinly wraps an initial
- :class:`~.asset_service.ListAssetsResponse` object, and
+ :class:`google.cloud.asset_v1p5beta1.types.ListAssetsResponse` object, and
provides an ``__iter__`` method to iterate through its
``assets`` field.
@@ -34,7 +43,7 @@ class ListAssetsPager:
through the ``assets`` field on the
corresponding responses.
- All the usual :class:`~.asset_service.ListAssetsResponse`
+ All the usual :class:`google.cloud.asset_v1p5beta1.types.ListAssetsResponse`
attributes are available on the pager. If multiple requests are made, only
the most recent response is retained, and thus used for attribute lookup.
"""
@@ -52,9 +61,9 @@ def __init__(
Args:
method (Callable): The method that was originally called, and
which instantiated this pager.
- request (:class:`~.asset_service.ListAssetsRequest`):
+ request (google.cloud.asset_v1p5beta1.types.ListAssetsRequest):
The initial request object.
- response (:class:`~.asset_service.ListAssetsResponse`):
+ response (google.cloud.asset_v1p5beta1.types.ListAssetsResponse):
The initial response object.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
@@ -87,7 +96,7 @@ class ListAssetsAsyncPager:
"""A pager for iterating through ``list_assets`` requests.
This class thinly wraps an initial
- :class:`~.asset_service.ListAssetsResponse` object, and
+ :class:`google.cloud.asset_v1p5beta1.types.ListAssetsResponse` object, and
provides an ``__aiter__`` method to iterate through its
``assets`` field.
@@ -96,7 +105,7 @@ class ListAssetsAsyncPager:
through the ``assets`` field on the
corresponding responses.
- All the usual :class:`~.asset_service.ListAssetsResponse`
+ All the usual :class:`google.cloud.asset_v1p5beta1.types.ListAssetsResponse`
attributes are available on the pager. If multiple requests are made, only
the most recent response is retained, and thus used for attribute lookup.
"""
@@ -114,9 +123,9 @@ def __init__(
Args:
method (Callable): The method that was originally called, and
which instantiated this pager.
- request (:class:`~.asset_service.ListAssetsRequest`):
+ request (google.cloud.asset_v1p5beta1.types.ListAssetsRequest):
The initial request object.
- response (:class:`~.asset_service.ListAssetsResponse`):
+ response (google.cloud.asset_v1p5beta1.types.ListAssetsResponse):
The initial response object.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py b/google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py
index 53bdd621..0eedae11 100644
--- a/google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py
+++ b/google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py
@@ -67,10 +67,10 @@ def __init__(
scope (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
+ 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.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
@@ -78,6 +78,9 @@ def __init__(
host += ":443"
self._host = host
+ # 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:
@@ -87,20 +90,17 @@ def __init__(
if credentials_file is not None:
credentials, _ = auth.load_credentials_from_file(
- credentials_file, scopes=scopes, quota_project_id=quota_project_id
+ credentials_file, scopes=self._scopes, quota_project_id=quota_project_id
)
elif credentials is None:
credentials, _ = auth.default(
- scopes=scopes, quota_project_id=quota_project_id
+ scopes=self._scopes, quota_project_id=quota_project_id
)
# Save the credentials.
self._credentials = credentials
- # Lifted into its own function so it can be stubbed out during tests.
- self._prep_wrapped_messages(client_info)
-
def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
@@ -113,6 +113,7 @@ def _prep_wrapped_messages(self, client_info):
predicate=retries.if_exception_type(
exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
+ deadline=60.0,
),
default_timeout=60.0,
client_info=client_info,
diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py b/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py
index 85dd47c6..b135deaa 100644
--- a/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py
+++ b/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py
@@ -57,6 +57,7 @@ def __init__(
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: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
@@ -87,6 +88,10 @@ def __init__(
``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):
@@ -101,72 +106,60 @@ 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
self._ssl_channel_credentials = None
- elif api_mtls_endpoint:
- warnings.warn(
- "api_mtls_endpoint and client_cert_source are deprecated",
- DeprecationWarning,
- )
-
- host = (
- api_mtls_endpoint
- if ":" in api_mtls_endpoint
- else api_mtls_endpoint + ":443"
- )
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ 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
-
- # 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,
- options=[
- ("grpc.max_send_message_length", -1),
- ("grpc.max_receive_message_length", -1),
- ],
- )
- self._ssl_channel_credentials = ssl_credentials
- else:
- host = host if ":" in host else host + ":443"
+ 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
+ )
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ # The base transport sets the host, credentials and scopes
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
- # create a new channel. The provided one is ignored.
+ if not self._grpc_channel:
self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
+ self._host,
+ credentials=self._credentials,
credentials_file=credentials_file,
- ssl_credentials=ssl_channel_credentials,
- scopes=scopes or self.AUTH_SCOPES,
+ scopes=self._scopes,
+ ssl_credentials=self._ssl_channel_credentials,
quota_project_id=quota_project_id,
options=[
("grpc.max_send_message_length", -1),
@@ -174,17 +167,8 @@ def __init__(
],
)
- self._stubs = {} # type: Dict[str, Callable]
-
- # Run the base constructor.
- super().__init__(
- host=host,
- credentials=credentials,
- credentials_file=credentials_file,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- client_info=client_info,
- )
+ # Wrap messages. This must be done after self._grpc_channel exists
+ self._prep_wrapped_messages(client_info)
@classmethod
def create_channel(
@@ -198,7 +182,7 @@ def create_channel(
) -> grpc.Channel:
"""Create and return a gRPC 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
diff --git a/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py b/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py
index 5c2586db..2df9b35f 100644
--- a/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py
+++ b/google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py
@@ -61,7 +61,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
@@ -101,6 +101,7 @@ def __init__(
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:
@@ -132,12 +133,16 @@ def __init__(
``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
+ 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:
@@ -146,72 +151,60 @@ 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
self._ssl_channel_credentials = None
- elif api_mtls_endpoint:
- warnings.warn(
- "api_mtls_endpoint and client_cert_source are deprecated",
- DeprecationWarning,
- )
-
- host = (
- api_mtls_endpoint
- if ":" in api_mtls_endpoint
- else api_mtls_endpoint + ":443"
- )
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ 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
-
- # 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,
- options=[
- ("grpc.max_send_message_length", -1),
- ("grpc.max_receive_message_length", -1),
- ],
- )
- self._ssl_channel_credentials = ssl_credentials
- else:
- host = host if ":" in host else host + ":443"
+ 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
+ )
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ # The base transport sets the host, credentials and scopes
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
- # create a new channel. The provided one is ignored.
+ if not self._grpc_channel:
self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
+ self._host,
+ credentials=self._credentials,
credentials_file=credentials_file,
- ssl_credentials=ssl_channel_credentials,
- scopes=scopes or self.AUTH_SCOPES,
+ scopes=self._scopes,
+ ssl_credentials=self._ssl_channel_credentials,
quota_project_id=quota_project_id,
options=[
("grpc.max_send_message_length", -1),
@@ -219,17 +212,8 @@ def __init__(
],
)
- # Run the base constructor.
- super().__init__(
- host=host,
- credentials=credentials,
- credentials_file=credentials_file,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- client_info=client_info,
- )
-
- self._stubs = {}
+ # Wrap messages. This must be done after self._grpc_channel exists
+ self._prep_wrapped_messages(client_info)
@property
def grpc_channel(self) -> aio.Channel:
diff --git a/google/cloud/asset_v1p5beta1/types/__init__.py b/google/cloud/asset_v1p5beta1/types/__init__.py
index c5930340..656ff62a 100644
--- a/google/cloud/asset_v1p5beta1/types/__init__.py
+++ b/google/cloud/asset_v1p5beta1/types/__init__.py
@@ -15,20 +15,20 @@
# limitations under the License.
#
-from .assets import (
- Asset,
- Resource,
-)
from .asset_service import (
ListAssetsRequest,
ListAssetsResponse,
ContentType,
)
+from .assets import (
+ Asset,
+ Resource,
+)
__all__ = (
- "Asset",
- "Resource",
"ListAssetsRequest",
"ListAssetsResponse",
"ContentType",
+ "Asset",
+ "Resource",
)
diff --git a/google/cloud/asset_v1p5beta1/types/asset_service.py b/google/cloud/asset_v1p5beta1/types/asset_service.py
index 69ae1423..6dc79759 100644
--- a/google/cloud/asset_v1p5beta1/types/asset_service.py
+++ b/google/cloud/asset_v1p5beta1/types/asset_service.py
@@ -47,7 +47,7 @@ class ListAssetsRequest(proto.Message):
(such as "organizations/123"), "projects/[project-number]"
(such as "projects/my-project-id"), or
"projects/[project-id]" (such as "projects/12345").
- read_time (~.timestamp.Timestamp):
+ read_time (google.protobuf.timestamp_pb2.Timestamp):
Timestamp to take an asset snapshot. This can
only be set to a timestamp between 2018-10-02
UTC (inclusive) and the current time. If not
@@ -62,7 +62,7 @@ class ListAssetsRequest(proto.Message):
Asset
Inventory `__
for all supported asset types.
- content_type (~.asset_service.ContentType):
+ content_type (google.cloud.asset_v1p5beta1.types.ContentType):
Asset content type. If not specified, no
content but the asset name will be returned.
page_size (int):
@@ -94,9 +94,9 @@ class ListAssetsResponse(proto.Message):
r"""ListAssets response.
Attributes:
- read_time (~.timestamp.Timestamp):
+ read_time (google.protobuf.timestamp_pb2.Timestamp):
Time the snapshot was taken.
- assets (Sequence[~.gca_assets.Asset]):
+ assets (Sequence[google.cloud.asset_v1p5beta1.types.Asset]):
Assets.
next_page_token (str):
Token to retrieve the next page of results.
diff --git a/google/cloud/asset_v1p5beta1/types/assets.py b/google/cloud/asset_v1p5beta1/types/assets.py
index dd32160e..8f62070c 100644
--- a/google/cloud/asset_v1p5beta1/types/assets.py
+++ b/google/cloud/asset_v1p5beta1/types/assets.py
@@ -45,23 +45,23 @@ class Asset(proto.Message):
asset_type (str):
Type of the asset. Example:
"compute.googleapis.com/Disk".
- resource (~.assets.Resource):
+ resource (google.cloud.asset_v1p5beta1.types.Resource):
Representation of the resource.
- iam_policy (~.policy.Policy):
+ iam_policy (google.iam.v1.policy_pb2.Policy):
Representation of the actual Cloud IAM policy
set on a cloud resource. For each resource,
there must be at most one Cloud IAM policy set
on it.
- org_policy (Sequence[~.orgpolicy.Policy]):
+ org_policy (Sequence[google.cloud.orgpolicy.v1.orgpolicy_pb2.Policy]):
Representation of the Cloud Organization
Policy set on an asset. For each asset, there
could be multiple Organization policies with
different constraints.
- access_policy (~.giav_access_policy.AccessPolicy):
+ access_policy (google.identity.accesscontextmanager.v1.access_policy_pb2.AccessPolicy):
- access_level (~.giav_access_level.AccessLevel):
+ access_level (google.identity.accesscontextmanager.v1.access_level_pb2.AccessLevel):
- service_perimeter (~.giav_service_perimeter.ServicePerimeter):
+ service_perimeter (google.identity.accesscontextmanager.v1.service_perimeter_pb2.ServicePerimeter):
ancestors (Sequence[str]):
Asset's ancestry path in Cloud Resource Manager (CRM)
@@ -145,7 +145,7 @@ class Resource(proto.Message):
``"//cloudresourcemanager.googleapis.com/projects/my_project_123"``.
For third-party assets, it is up to the users to define.
- data (~.struct.Struct):
+ data (google.protobuf.struct_pb2.Struct):
The content of the resource, in which some
sensitive fields are scrubbed away and may not
be present.
diff --git a/noxfile.py b/noxfile.py
index 41eeb037..6e8aafb9 100644
--- a/noxfile.py
+++ b/noxfile.py
@@ -18,6 +18,7 @@
from __future__ import absolute_import
import os
+import pathlib
import shutil
import nox
@@ -30,6 +31,22 @@
SYSTEM_TEST_PYTHON_VERSIONS = ["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)
def lint(session):
@@ -70,17 +87,21 @@ 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",
+ constraints_path = str(
+ CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
)
- session.install("-e", ".")
+ 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(
"py.test",
"--quiet",
+ f"--junitxml=unit_{session.python}_sponge_log.xml",
"--cov=google/cloud",
"--cov=tests/unit",
"--cov-append",
@@ -101,6 +122,9 @@ 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")
@@ -110,6 +134,9 @@ def system(session):
# 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)
@@ -122,16 +149,26 @@ 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:
- session.run("py.test", "--quiet", system_test_path, *session.posargs)
+ session.run(
+ "py.test",
+ "--quiet",
+ f"--junitxml=system_{session.python}_sponge_log.xml",
+ system_test_path,
+ *session.posargs,
+ )
if system_test_folder_exists:
- session.run("py.test", "--quiet", system_test_folder_path, *session.posargs)
+ session.run(
+ "py.test",
+ "--quiet",
+ f"--junitxml=system_{session.python}_sponge_log.xml",
+ system_test_folder_path,
+ *session.posargs,
+ )
@nox.session(python=DEFAULT_PYTHON_VERSION)
@@ -142,7 +179,7 @@ def cover(session):
test runs (not system test runs), and then erases coverage data.
"""
session.install("coverage", "pytest-cov")
- session.run("coverage", "report", "--show-missing", "--fail-under=99")
+ session.run("coverage", "report", "--show-missing", "--fail-under=98")
session.run("coverage", "erase")
@@ -174,9 +211,7 @@ def docfx(session):
"""Build the docfx yaml files for this library."""
session.install("-e", ".")
- # sphinx-docfx-yaml supports up to sphinx version 1.5.5.
- # https://github.com/docascode/sphinx-docfx-yaml/issues/97
- session.install("sphinx==1.5.5", "alabaster", "recommonmark", "sphinx-docfx-yaml")
+ session.install("sphinx", "alabaster", "recommonmark", "gcp-sphinx-docfx-yaml")
shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True)
session.run(
diff --git a/renovate.json b/renovate.json
index 4fa94931..f08bc22c 100644
--- a/renovate.json
+++ b/renovate.json
@@ -1,5 +1,6 @@
{
"extends": [
"config:base", ":preserveSemverRanges"
- ]
+ ],
+ "ignorePaths": [".pre-commit-config.yaml"]
}
diff --git a/samples/snippets/noxfile.py b/samples/snippets/noxfile.py
index bca0522e..97bf7da8 100644
--- a/samples/snippets/noxfile.py
+++ b/samples/snippets/noxfile.py
@@ -85,7 +85,7 @@ def get_pytest_env_vars() -> Dict[str, str]:
# DO NOT EDIT - automatically generated.
# All versions used to tested samples.
-ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"]
+ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"]
# Any default versions that should be ignored.
IGNORED_VERSIONS = TEST_CONFIG['ignored_versions']
diff --git a/setup.py b/setup.py
index a7881597..9bf1e02f 100644
--- a/setup.py
+++ b/setup.py
@@ -28,15 +28,16 @@
# 'Development Status :: 5 - Production/Stable'
release_status = "Development Status :: 5 - Production/Stable"
dependencies = [
- "google-api-core[grpc] >= 1.22.0, < 2.0.0dev",
+ "google-api-core[grpc] >= 1.22.2, < 2.0.0dev",
"grpc-google-iam-v1 >= 0.12.3, < 0.13dev",
"google-cloud-access-context-manager >= 0.1.2, < 0.2.0dev",
"google-cloud-org-policy>=0.1.2, <0.2.1",
"google-cloud-os-config >= 1.0.0, <2.0.0dev",
- "proto-plus >= 0.4.0",
- "libcst >= 0.2.5",
+ "proto-plus >= 1.10.0",
]
+extras = {"libcst": "libcst >= 0.2.5"}
+
# Setup boilerplate below this line.
package_root = os.path.abspath(os.path.dirname(__file__))
@@ -83,6 +84,7 @@
packages=packages,
namespace_packages=namespaces,
install_requires=dependencies,
+ extras_requires=extras,
python_requires=">=3.6",
scripts=[
"scripts/fixup_asset_v1_keywords.py",
diff --git a/synth.metadata b/synth.metadata
index 3364ddad..766f2998 100644
--- a/synth.metadata
+++ b/synth.metadata
@@ -3,30 +3,30 @@
{
"git": {
"name": ".",
- "remote": "https://github.com/googleapis/python-asset.git",
- "sha": "8a517bf0c4fc6f58dd6f56c87494c2ffd3bfe5e1"
+ "remote": "git@github.com:googleapis/python-asset.git",
+ "sha": "692651851404499c8e62fc2859b967b5558e7e0d"
}
},
{
"git": {
"name": "googleapis",
"remote": "https://github.com/googleapis/googleapis.git",
- "sha": "bfdb1df3876564228c43c3ea64edf5f90d10d92f",
- "internalRef": "348500610"
+ "sha": "56fc6d43fed71188d7e18f3ca003544646c4ab35",
+ "internalRef": "366346972"
}
},
{
"git": {
"name": "synthtool",
"remote": "https://github.com/googleapis/synthtool.git",
- "sha": "41a4e56982620d3edcf110d76f4fcdfdec471ac8"
+ "sha": "ff39353f34a36e7643b86e97724e4027ab466dc6"
}
},
{
"git": {
"name": "synthtool",
"remote": "https://github.com/googleapis/synthtool.git",
- "sha": "41a4e56982620d3edcf110d76f4fcdfdec471ac8"
+ "sha": "ff39353f34a36e7643b86e97724e4027ab466dc6"
}
}
],
@@ -76,170 +76,5 @@
"generator": "bazel"
}
}
- ],
- "generatedFiles": [
- ".flake8",
- ".github/CONTRIBUTING.md",
- ".github/ISSUE_TEMPLATE/bug_report.md",
- ".github/ISSUE_TEMPLATE/feature_request.md",
- ".github/ISSUE_TEMPLATE/support_request.md",
- ".github/PULL_REQUEST_TEMPLATE.md",
- ".github/release-please.yml",
- ".github/snippet-bot.yml",
- ".gitignore",
- ".kokoro/build.sh",
- ".kokoro/continuous/common.cfg",
- ".kokoro/continuous/continuous.cfg",
- ".kokoro/docker/docs/Dockerfile",
- ".kokoro/docker/docs/fetch_gpg_keys.sh",
- ".kokoro/docs/common.cfg",
- ".kokoro/docs/docs-presubmit.cfg",
- ".kokoro/docs/docs.cfg",
- ".kokoro/populate-secrets.sh",
- ".kokoro/presubmit/common.cfg",
- ".kokoro/presubmit/presubmit.cfg",
- ".kokoro/publish-docs.sh",
- ".kokoro/release.sh",
- ".kokoro/release/common.cfg",
- ".kokoro/release/release.cfg",
- ".kokoro/samples/lint/common.cfg",
- ".kokoro/samples/lint/continuous.cfg",
- ".kokoro/samples/lint/periodic.cfg",
- ".kokoro/samples/lint/presubmit.cfg",
- ".kokoro/samples/python3.6/common.cfg",
- ".kokoro/samples/python3.6/continuous.cfg",
- ".kokoro/samples/python3.6/periodic.cfg",
- ".kokoro/samples/python3.6/presubmit.cfg",
- ".kokoro/samples/python3.7/common.cfg",
- ".kokoro/samples/python3.7/continuous.cfg",
- ".kokoro/samples/python3.7/periodic.cfg",
- ".kokoro/samples/python3.7/presubmit.cfg",
- ".kokoro/samples/python3.8/common.cfg",
- ".kokoro/samples/python3.8/continuous.cfg",
- ".kokoro/samples/python3.8/periodic.cfg",
- ".kokoro/samples/python3.8/presubmit.cfg",
- ".kokoro/test-samples.sh",
- ".kokoro/trampoline.sh",
- ".kokoro/trampoline_v2.sh",
- ".pre-commit-config.yaml",
- ".trampolinerc",
- "CODE_OF_CONDUCT.md",
- "CONTRIBUTING.rst",
- "LICENSE",
- "MANIFEST.in",
- "docs/_static/custom.css",
- "docs/_templates/layout.html",
- "docs/asset_v1/services.rst",
- "docs/asset_v1/types.rst",
- "docs/asset_v1p1beta1/services.rst",
- "docs/asset_v1p1beta1/types.rst",
- "docs/asset_v1p2beta1/services.rst",
- "docs/asset_v1p2beta1/types.rst",
- "docs/asset_v1p4beta1/services.rst",
- "docs/asset_v1p4beta1/types.rst",
- "docs/asset_v1p5beta1/services.rst",
- "docs/asset_v1p5beta1/types.rst",
- "docs/conf.py",
- "docs/multiprocessing.rst",
- "google/cloud/asset/__init__.py",
- "google/cloud/asset/py.typed",
- "google/cloud/asset_v1/__init__.py",
- "google/cloud/asset_v1/py.typed",
- "google/cloud/asset_v1/services/__init__.py",
- "google/cloud/asset_v1/services/asset_service/__init__.py",
- "google/cloud/asset_v1/services/asset_service/async_client.py",
- "google/cloud/asset_v1/services/asset_service/client.py",
- "google/cloud/asset_v1/services/asset_service/pagers.py",
- "google/cloud/asset_v1/services/asset_service/transports/__init__.py",
- "google/cloud/asset_v1/services/asset_service/transports/base.py",
- "google/cloud/asset_v1/services/asset_service/transports/grpc.py",
- "google/cloud/asset_v1/services/asset_service/transports/grpc_asyncio.py",
- "google/cloud/asset_v1/types/__init__.py",
- "google/cloud/asset_v1/types/asset_service.py",
- "google/cloud/asset_v1/types/assets.py",
- "google/cloud/asset_v1p1beta1/__init__.py",
- "google/cloud/asset_v1p1beta1/py.typed",
- "google/cloud/asset_v1p1beta1/services/__init__.py",
- "google/cloud/asset_v1p1beta1/services/asset_service/__init__.py",
- "google/cloud/asset_v1p1beta1/services/asset_service/async_client.py",
- "google/cloud/asset_v1p1beta1/services/asset_service/client.py",
- "google/cloud/asset_v1p1beta1/services/asset_service/pagers.py",
- "google/cloud/asset_v1p1beta1/services/asset_service/transports/__init__.py",
- "google/cloud/asset_v1p1beta1/services/asset_service/transports/base.py",
- "google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc.py",
- "google/cloud/asset_v1p1beta1/services/asset_service/transports/grpc_asyncio.py",
- "google/cloud/asset_v1p1beta1/types/__init__.py",
- "google/cloud/asset_v1p1beta1/types/asset_service.py",
- "google/cloud/asset_v1p1beta1/types/assets.py",
- "google/cloud/asset_v1p2beta1/__init__.py",
- "google/cloud/asset_v1p2beta1/py.typed",
- "google/cloud/asset_v1p2beta1/services/__init__.py",
- "google/cloud/asset_v1p2beta1/services/asset_service/__init__.py",
- "google/cloud/asset_v1p2beta1/services/asset_service/async_client.py",
- "google/cloud/asset_v1p2beta1/services/asset_service/client.py",
- "google/cloud/asset_v1p2beta1/services/asset_service/transports/__init__.py",
- "google/cloud/asset_v1p2beta1/services/asset_service/transports/base.py",
- "google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc.py",
- "google/cloud/asset_v1p2beta1/services/asset_service/transports/grpc_asyncio.py",
- "google/cloud/asset_v1p2beta1/types/__init__.py",
- "google/cloud/asset_v1p2beta1/types/asset_service.py",
- "google/cloud/asset_v1p2beta1/types/assets.py",
- "google/cloud/asset_v1p4beta1/__init__.py",
- "google/cloud/asset_v1p4beta1/py.typed",
- "google/cloud/asset_v1p4beta1/services/__init__.py",
- "google/cloud/asset_v1p4beta1/services/asset_service/__init__.py",
- "google/cloud/asset_v1p4beta1/services/asset_service/async_client.py",
- "google/cloud/asset_v1p4beta1/services/asset_service/client.py",
- "google/cloud/asset_v1p4beta1/services/asset_service/transports/__init__.py",
- "google/cloud/asset_v1p4beta1/services/asset_service/transports/base.py",
- "google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc.py",
- "google/cloud/asset_v1p4beta1/services/asset_service/transports/grpc_asyncio.py",
- "google/cloud/asset_v1p4beta1/types/__init__.py",
- "google/cloud/asset_v1p4beta1/types/asset_service.py",
- "google/cloud/asset_v1p4beta1/types/assets.py",
- "google/cloud/asset_v1p5beta1/__init__.py",
- "google/cloud/asset_v1p5beta1/py.typed",
- "google/cloud/asset_v1p5beta1/services/__init__.py",
- "google/cloud/asset_v1p5beta1/services/asset_service/__init__.py",
- "google/cloud/asset_v1p5beta1/services/asset_service/async_client.py",
- "google/cloud/asset_v1p5beta1/services/asset_service/client.py",
- "google/cloud/asset_v1p5beta1/services/asset_service/pagers.py",
- "google/cloud/asset_v1p5beta1/services/asset_service/transports/__init__.py",
- "google/cloud/asset_v1p5beta1/services/asset_service/transports/base.py",
- "google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc.py",
- "google/cloud/asset_v1p5beta1/services/asset_service/transports/grpc_asyncio.py",
- "google/cloud/asset_v1p5beta1/types/__init__.py",
- "google/cloud/asset_v1p5beta1/types/asset_service.py",
- "google/cloud/asset_v1p5beta1/types/assets.py",
- "mypy.ini",
- "noxfile.py",
- "renovate.json",
- "samples/AUTHORING_GUIDE.md",
- "samples/CONTRIBUTING.md",
- "samples/snippets/noxfile.py",
- "scripts/decrypt-secrets.sh",
- "scripts/fixup_asset_v1_keywords.py",
- "scripts/fixup_asset_v1p1beta1_keywords.py",
- "scripts/fixup_asset_v1p2beta1_keywords.py",
- "scripts/fixup_asset_v1p4beta1_keywords.py",
- "scripts/fixup_asset_v1p5beta1_keywords.py",
- "scripts/readme-gen/readme_gen.py",
- "scripts/readme-gen/templates/README.tmpl.rst",
- "scripts/readme-gen/templates/auth.tmpl.rst",
- "scripts/readme-gen/templates/auth_api_key.tmpl.rst",
- "scripts/readme-gen/templates/install_deps.tmpl.rst",
- "scripts/readme-gen/templates/install_portaudio.tmpl.rst",
- "setup.cfg",
- "testing/.gitignore",
- "tests/unit/gapic/asset_v1/__init__.py",
- "tests/unit/gapic/asset_v1/test_asset_service.py",
- "tests/unit/gapic/asset_v1p1beta1/__init__.py",
- "tests/unit/gapic/asset_v1p1beta1/test_asset_service.py",
- "tests/unit/gapic/asset_v1p2beta1/__init__.py",
- "tests/unit/gapic/asset_v1p2beta1/test_asset_service.py",
- "tests/unit/gapic/asset_v1p4beta1/__init__.py",
- "tests/unit/gapic/asset_v1p4beta1/test_asset_service.py",
- "tests/unit/gapic/asset_v1p5beta1/__init__.py",
- "tests/unit/gapic/asset_v1p5beta1/test_asset_service.py"
]
}
\ No newline at end of file
diff --git a/synth.py b/synth.py
index 091a879c..10a4b93f 100644
--- a/synth.py
+++ b/synth.py
@@ -78,7 +78,7 @@ def parse_asset_path.*?@staticmethod""",
templated_files = common.py_library(
samples=True, # set to True only if there are samples
microgenerator=True,
- cov_level=99,
+ cov_level=98,
)
s.move(templated_files, excludes=[".coveragerc"]) # microgenerator has a good .coveragerc file
diff --git a/testing/constraints-3.6.txt b/testing/constraints-3.6.txt
index 6517c409..206057ed 100644
--- a/testing/constraints-3.6.txt
+++ b/testing/constraints-3.6.txt
@@ -5,10 +5,10 @@
#
# 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.22.0
+google-api-core==1.22.2
grpc-google-iam-v1==0.12.3
google-cloud-access-context-manager==0.1.2
google-cloud-org-policy==0.1.2
google-cloud-os-config==1.0.0
-proto-plus==0.4.0
-libcst==0.2.5
\ No newline at end of file
+proto-plus==1.10.0
+libcst==0.2.5
diff --git a/tests/unit/gapic/asset_v1/__init__.py b/tests/unit/gapic/asset_v1/__init__.py
index 8b137891..42ffdf2b 100644
--- a/tests/unit/gapic/asset_v1/__init__.py
+++ b/tests/unit/gapic/asset_v1/__init__.py
@@ -1 +1,16 @@
+# -*- 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/tests/unit/gapic/asset_v1/test_asset_service.py b/tests/unit/gapic/asset_v1/test_asset_service.py
index 69785f09..ed73b1f9 100644
--- a/tests/unit/gapic/asset_v1/test_asset_service.py
+++ b/tests/unit/gapic/asset_v1/test_asset_service.py
@@ -90,7 +90,22 @@ def test__get_default_mtls_endpoint():
assert AssetServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi
-@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient])
+@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient,])
+def test_asset_service_client_from_service_account_info(client_class):
+ creds = credentials.AnonymousCredentials()
+ with mock.patch.object(
+ service_account.Credentials, "from_service_account_info"
+ ) as factory:
+ factory.return_value = creds
+ info = {"valid": True}
+ client = client_class.from_service_account_info(info)
+ assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
+
+ assert client.transport._host == "cloudasset.googleapis.com:443"
+
+
+@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient,])
def test_asset_service_client_from_service_account_file(client_class):
creds = credentials.AnonymousCredentials()
with mock.patch.object(
@@ -99,16 +114,21 @@ def test_asset_service_client_from_service_account_file(client_class):
factory.return_value = creds
client = client_class.from_service_account_file("dummy/file/path.json")
assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
client = client_class.from_service_account_json("dummy/file/path.json")
assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
assert client.transport._host == "cloudasset.googleapis.com:443"
def test_asset_service_client_get_transport_class():
transport = AssetServiceClient.get_transport_class()
- assert transport == transports.AssetServiceGrpcTransport
+ available_transports = [
+ transports.AssetServiceGrpcTransport,
+ ]
+ assert transport in available_transports
transport = AssetServiceClient.get_transport_class("grpc")
assert transport == transports.AssetServiceGrpcTransport
@@ -157,7 +177,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -173,7 +193,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -189,7 +209,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_MTLS_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -217,7 +237,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id="octopus",
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -266,29 +286,25 @@ def test_asset_service_client_mtls_env_auto(
client_cert_source=client_cert_source_callback
)
with mock.patch.object(transport_class, "__init__") as patched:
- ssl_channel_creds = mock.Mock()
- with mock.patch(
- "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
- ):
- patched.return_value = None
- client = client_class(client_options=options)
+ patched.return_value = None
+ client = client_class(client_options=options)
- if use_client_cert_env == "false":
- expected_ssl_channel_creds = None
- expected_host = client.DEFAULT_ENDPOINT
- else:
- expected_ssl_channel_creds = ssl_channel_creds
- expected_host = client.DEFAULT_MTLS_ENDPOINT
+ if use_client_cert_env == "false":
+ expected_client_cert_source = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_client_cert_source = client_cert_source_callback
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=expected_host,
- scopes=None,
- ssl_channel_credentials=expected_ssl_channel_creds,
- quota_project_id=None,
- client_info=transports.base.DEFAULT_CLIENT_INFO,
- )
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ client_cert_source_for_mtls=expected_client_cert_source,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
# Check the case ADC client cert is provided. Whether client cert is used depends on
# GOOGLE_API_USE_CLIENT_CERTIFICATE value.
@@ -297,66 +313,53 @@ def test_asset_service_client_mtls_env_auto(
):
with mock.patch.object(transport_class, "__init__") as patched:
with mock.patch(
- "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ "google.auth.transport.mtls.has_default_client_cert_source",
+ return_value=True,
):
with mock.patch(
- "google.auth.transport.grpc.SslCredentials.is_mtls",
- new_callable=mock.PropertyMock,
- ) as is_mtls_mock:
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.ssl_credentials",
- new_callable=mock.PropertyMock,
- ) as ssl_credentials_mock:
- if use_client_cert_env == "false":
- is_mtls_mock.return_value = False
- ssl_credentials_mock.return_value = None
- expected_host = client.DEFAULT_ENDPOINT
- expected_ssl_channel_creds = None
- else:
- is_mtls_mock.return_value = True
- ssl_credentials_mock.return_value = mock.Mock()
- expected_host = client.DEFAULT_MTLS_ENDPOINT
- expected_ssl_channel_creds = (
- ssl_credentials_mock.return_value
- )
-
- patched.return_value = None
- client = client_class()
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=expected_host,
- scopes=None,
- ssl_channel_credentials=expected_ssl_channel_creds,
- quota_project_id=None,
- client_info=transports.base.DEFAULT_CLIENT_INFO,
- )
+ "google.auth.transport.mtls.default_client_cert_source",
+ return_value=client_cert_source_callback,
+ ):
+ if use_client_cert_env == "false":
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_client_cert_source = None
+ else:
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_client_cert_source = client_cert_source_callback
- # Check the case client_cert_source and ADC client cert are not provided.
- with mock.patch.dict(
- os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
- ):
- with mock.patch.object(transport_class, "__init__") as patched:
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
- ):
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.is_mtls",
- new_callable=mock.PropertyMock,
- ) as is_mtls_mock:
- is_mtls_mock.return_value = False
patched.return_value = None
client = client_class()
patched.assert_called_once_with(
credentials=None,
credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
+ host=expected_host,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=expected_client_cert_source,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.mtls.has_default_client_cert_source",
+ return_value=False,
+ ):
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ client_cert_source_for_mtls=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
@pytest.mark.parametrize(
"client_class,transport_class,transport_name",
@@ -382,7 +385,7 @@ def test_asset_service_client_client_options_scopes(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=["1", "2"],
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -412,7 +415,7 @@ def test_asset_service_client_client_options_credentials_file(
credentials_file="credentials.json",
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -429,7 +432,7 @@ def test_asset_service_client_client_options_from_dict():
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -467,6 +470,22 @@ def test_export_assets_from_dict():
test_export_assets(request_type=dict)
+def test_export_assets_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.export_assets), "__call__") as call:
+ client.export_assets()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.ExportAssetsRequest()
+
+
@pytest.mark.asyncio
async def test_export_assets_async(
transport: str = "grpc_asyncio", request_type=asset_service.ExportAssetsRequest
@@ -589,6 +608,24 @@ def test_batch_get_assets_history_from_dict():
test_batch_get_assets_history(request_type=dict)
+def test_batch_get_assets_history_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client.transport.batch_get_assets_history), "__call__"
+ ) as call:
+ client.batch_get_assets_history()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.BatchGetAssetsHistoryRequest()
+
+
@pytest.mark.asyncio
async def test_batch_get_assets_history_async(
transport: str = "grpc_asyncio",
@@ -729,6 +766,22 @@ def test_create_feed_from_dict():
test_create_feed(request_type=dict)
+def test_create_feed_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.create_feed), "__call__") as call:
+ client.create_feed()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.CreateFeedRequest()
+
+
@pytest.mark.asyncio
async def test_create_feed_async(
transport: str = "grpc_asyncio", request_type=asset_service.CreateFeedRequest
@@ -936,6 +989,22 @@ def test_get_feed_from_dict():
test_get_feed(request_type=dict)
+def test_get_feed_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.get_feed), "__call__") as call:
+ client.get_feed()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.GetFeedRequest()
+
+
@pytest.mark.asyncio
async def test_get_feed_async(
transport: str = "grpc_asyncio", request_type=asset_service.GetFeedRequest
@@ -1132,6 +1201,22 @@ def test_list_feeds_from_dict():
test_list_feeds(request_type=dict)
+def test_list_feeds_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.list_feeds), "__call__") as call:
+ client.list_feeds()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.ListFeedsRequest()
+
+
@pytest.mark.asyncio
async def test_list_feeds_async(
transport: str = "grpc_asyncio", request_type=asset_service.ListFeedsRequest
@@ -1332,6 +1417,22 @@ def test_update_feed_from_dict():
test_update_feed(request_type=dict)
+def test_update_feed_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.update_feed), "__call__") as call:
+ client.update_feed()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.UpdateFeedRequest()
+
+
@pytest.mark.asyncio
async def test_update_feed_async(
transport: str = "grpc_asyncio", request_type=asset_service.UpdateFeedRequest
@@ -1529,6 +1630,22 @@ def test_delete_feed_from_dict():
test_delete_feed(request_type=dict)
+def test_delete_feed_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.delete_feed), "__call__") as call:
+ client.delete_feed()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.DeleteFeedRequest()
+
+
@pytest.mark.asyncio
async def test_delete_feed_async(
transport: str = "grpc_asyncio", request_type=asset_service.DeleteFeedRequest
@@ -1716,6 +1833,24 @@ def test_search_all_resources_from_dict():
test_search_all_resources(request_type=dict)
+def test_search_all_resources_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client.transport.search_all_resources), "__call__"
+ ) as call:
+ client.search_all_resources()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.SearchAllResourcesRequest()
+
+
@pytest.mark.asyncio
async def test_search_all_resources_async(
transport: str = "grpc_asyncio",
@@ -2096,6 +2231,24 @@ def test_search_all_iam_policies_from_dict():
test_search_all_iam_policies(request_type=dict)
+def test_search_all_iam_policies_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client.transport.search_all_iam_policies), "__call__"
+ ) as call:
+ client.search_all_iam_policies()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.SearchAllIamPoliciesRequest()
+
+
@pytest.mark.asyncio
async def test_search_all_iam_policies_async(
transport: str = "grpc_asyncio",
@@ -2480,6 +2633,24 @@ def test_analyze_iam_policy_from_dict():
test_analyze_iam_policy(request_type=dict)
+def test_analyze_iam_policy_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client.transport.analyze_iam_policy), "__call__"
+ ) as call:
+ client.analyze_iam_policy()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.AnalyzeIamPolicyRequest()
+
+
@pytest.mark.asyncio
async def test_analyze_iam_policy_async(
transport: str = "grpc_asyncio", request_type=asset_service.AnalyzeIamPolicyRequest
@@ -2616,6 +2787,24 @@ def test_analyze_iam_policy_longrunning_from_dict():
test_analyze_iam_policy_longrunning(request_type=dict)
+def test_analyze_iam_policy_longrunning_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client.transport.analyze_iam_policy_longrunning), "__call__"
+ ) as call:
+ client.analyze_iam_policy_longrunning()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.AnalyzeIamPolicyLongrunningRequest()
+
+
@pytest.mark.asyncio
async def test_analyze_iam_policy_longrunning_async(
transport: str = "grpc_asyncio",
@@ -2772,7 +2961,10 @@ def test_transport_get_channel():
@pytest.mark.parametrize(
"transport_class",
- [transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
+ [
+ transports.AssetServiceGrpcTransport,
+ transports.AssetServiceGrpcAsyncIOTransport,
+ ],
)
def test_transport_adc(transport_class):
# Test default credentials are used if not provided.
@@ -2887,6 +3079,48 @@ def test_asset_service_transport_auth_adc():
)
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
+)
+def test_asset_service_grpc_transport_client_cert_source_for_mtls(transport_class):
+ cred = 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=("https://www.googleapis.com/auth/cloud-platform",),
+ 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_asset_service_host_no_port():
client = AssetServiceClient(
credentials=credentials.AnonymousCredentials(),
@@ -2908,7 +3142,7 @@ def test_asset_service_host_with_port():
def test_asset_service_grpc_transport_channel():
- channel = grpc.insecure_channel("http://localhost/")
+ channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials())
# Check that channel is used if provided.
transport = transports.AssetServiceGrpcTransport(
@@ -2920,7 +3154,7 @@ def test_asset_service_grpc_transport_channel():
def test_asset_service_grpc_asyncio_transport_channel():
- channel = aio.insecure_channel("http://localhost/")
+ channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials())
# Check that channel is used if provided.
transport = transports.AssetServiceGrpcAsyncIOTransport(
@@ -2931,6 +3165,8 @@ def test_asset_service_grpc_asyncio_transport_channel():
assert transport._ssl_channel_credentials == None
+# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are
+# removed from grpc/grpc_asyncio transport constructor.
@pytest.mark.parametrize(
"transport_class",
[transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
@@ -2940,7 +3176,7 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_
"grpc.ssl_channel_credentials", autospec=True
) as grpc_ssl_channel_cred:
with mock.patch.object(
- transport_class, "create_channel", autospec=True
+ transport_class, "create_channel"
) as grpc_create_channel:
mock_ssl_cred = mock.Mock()
grpc_ssl_channel_cred.return_value = mock_ssl_cred
@@ -2978,6 +3214,8 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_
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.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
@@ -2990,7 +3228,7 @@ def test_asset_service_transport_channel_mtls_with_adc(transport_class):
ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
):
with mock.patch.object(
- transport_class, "create_channel", autospec=True
+ transport_class, "create_channel"
) as grpc_create_channel:
mock_grpc_channel = mock.Mock()
grpc_create_channel.return_value = mock_grpc_channel
diff --git a/tests/unit/gapic/asset_v1p1beta1/__init__.py b/tests/unit/gapic/asset_v1p1beta1/__init__.py
index 8b137891..42ffdf2b 100644
--- a/tests/unit/gapic/asset_v1p1beta1/__init__.py
+++ b/tests/unit/gapic/asset_v1p1beta1/__init__.py
@@ -1 +1,16 @@
+# -*- 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/tests/unit/gapic/asset_v1p1beta1/test_asset_service.py b/tests/unit/gapic/asset_v1p1beta1/test_asset_service.py
index b818753e..c98df4a7 100644
--- a/tests/unit/gapic/asset_v1p1beta1/test_asset_service.py
+++ b/tests/unit/gapic/asset_v1p1beta1/test_asset_service.py
@@ -82,7 +82,22 @@ def test__get_default_mtls_endpoint():
assert AssetServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi
-@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient])
+@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient,])
+def test_asset_service_client_from_service_account_info(client_class):
+ creds = credentials.AnonymousCredentials()
+ with mock.patch.object(
+ service_account.Credentials, "from_service_account_info"
+ ) as factory:
+ factory.return_value = creds
+ info = {"valid": True}
+ client = client_class.from_service_account_info(info)
+ assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
+
+ assert client.transport._host == "cloudasset.googleapis.com:443"
+
+
+@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient,])
def test_asset_service_client_from_service_account_file(client_class):
creds = credentials.AnonymousCredentials()
with mock.patch.object(
@@ -91,16 +106,21 @@ def test_asset_service_client_from_service_account_file(client_class):
factory.return_value = creds
client = client_class.from_service_account_file("dummy/file/path.json")
assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
client = client_class.from_service_account_json("dummy/file/path.json")
assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
assert client.transport._host == "cloudasset.googleapis.com:443"
def test_asset_service_client_get_transport_class():
transport = AssetServiceClient.get_transport_class()
- assert transport == transports.AssetServiceGrpcTransport
+ available_transports = [
+ transports.AssetServiceGrpcTransport,
+ ]
+ assert transport in available_transports
transport = AssetServiceClient.get_transport_class("grpc")
assert transport == transports.AssetServiceGrpcTransport
@@ -149,7 +169,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -165,7 +185,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -181,7 +201,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_MTLS_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -209,7 +229,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id="octopus",
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -258,29 +278,25 @@ def test_asset_service_client_mtls_env_auto(
client_cert_source=client_cert_source_callback
)
with mock.patch.object(transport_class, "__init__") as patched:
- ssl_channel_creds = mock.Mock()
- with mock.patch(
- "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
- ):
- patched.return_value = None
- client = client_class(client_options=options)
+ patched.return_value = None
+ client = client_class(client_options=options)
- if use_client_cert_env == "false":
- expected_ssl_channel_creds = None
- expected_host = client.DEFAULT_ENDPOINT
- else:
- expected_ssl_channel_creds = ssl_channel_creds
- expected_host = client.DEFAULT_MTLS_ENDPOINT
+ if use_client_cert_env == "false":
+ expected_client_cert_source = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_client_cert_source = client_cert_source_callback
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=expected_host,
- scopes=None,
- ssl_channel_credentials=expected_ssl_channel_creds,
- quota_project_id=None,
- client_info=transports.base.DEFAULT_CLIENT_INFO,
- )
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ client_cert_source_for_mtls=expected_client_cert_source,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
# Check the case ADC client cert is provided. Whether client cert is used depends on
# GOOGLE_API_USE_CLIENT_CERTIFICATE value.
@@ -289,66 +305,53 @@ def test_asset_service_client_mtls_env_auto(
):
with mock.patch.object(transport_class, "__init__") as patched:
with mock.patch(
- "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ "google.auth.transport.mtls.has_default_client_cert_source",
+ return_value=True,
):
with mock.patch(
- "google.auth.transport.grpc.SslCredentials.is_mtls",
- new_callable=mock.PropertyMock,
- ) as is_mtls_mock:
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.ssl_credentials",
- new_callable=mock.PropertyMock,
- ) as ssl_credentials_mock:
- if use_client_cert_env == "false":
- is_mtls_mock.return_value = False
- ssl_credentials_mock.return_value = None
- expected_host = client.DEFAULT_ENDPOINT
- expected_ssl_channel_creds = None
- else:
- is_mtls_mock.return_value = True
- ssl_credentials_mock.return_value = mock.Mock()
- expected_host = client.DEFAULT_MTLS_ENDPOINT
- expected_ssl_channel_creds = (
- ssl_credentials_mock.return_value
- )
-
- patched.return_value = None
- client = client_class()
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=expected_host,
- scopes=None,
- ssl_channel_credentials=expected_ssl_channel_creds,
- quota_project_id=None,
- client_info=transports.base.DEFAULT_CLIENT_INFO,
- )
+ "google.auth.transport.mtls.default_client_cert_source",
+ return_value=client_cert_source_callback,
+ ):
+ if use_client_cert_env == "false":
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_client_cert_source = None
+ else:
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_client_cert_source = client_cert_source_callback
- # Check the case client_cert_source and ADC client cert are not provided.
- with mock.patch.dict(
- os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
- ):
- with mock.patch.object(transport_class, "__init__") as patched:
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
- ):
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.is_mtls",
- new_callable=mock.PropertyMock,
- ) as is_mtls_mock:
- is_mtls_mock.return_value = False
patched.return_value = None
client = client_class()
patched.assert_called_once_with(
credentials=None,
credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
+ host=expected_host,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=expected_client_cert_source,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.mtls.has_default_client_cert_source",
+ return_value=False,
+ ):
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ client_cert_source_for_mtls=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
@pytest.mark.parametrize(
"client_class,transport_class,transport_name",
@@ -374,7 +377,7 @@ def test_asset_service_client_client_options_scopes(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=["1", "2"],
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -404,7 +407,7 @@ def test_asset_service_client_client_options_credentials_file(
credentials_file="credentials.json",
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -421,7 +424,7 @@ def test_asset_service_client_client_options_from_dict():
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -466,6 +469,24 @@ def test_search_all_resources_from_dict():
test_search_all_resources(request_type=dict)
+def test_search_all_resources_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client.transport.search_all_resources), "__call__"
+ ) as call:
+ client.search_all_resources()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.SearchAllResourcesRequest()
+
+
@pytest.mark.asyncio
async def test_search_all_resources_async(
transport: str = "grpc_asyncio",
@@ -858,6 +879,24 @@ def test_search_all_iam_policies_from_dict():
test_search_all_iam_policies(request_type=dict)
+def test_search_all_iam_policies_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client.transport.search_all_iam_policies), "__call__"
+ ) as call:
+ client.search_all_iam_policies()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.SearchAllIamPoliciesRequest()
+
+
@pytest.mark.asyncio
async def test_search_all_iam_policies_async(
transport: str = "grpc_asyncio",
@@ -1261,7 +1300,10 @@ def test_transport_get_channel():
@pytest.mark.parametrize(
"transport_class",
- [transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
+ [
+ transports.AssetServiceGrpcTransport,
+ transports.AssetServiceGrpcAsyncIOTransport,
+ ],
)
def test_transport_adc(transport_class):
# Test default credentials are used if not provided.
@@ -1362,6 +1404,48 @@ def test_asset_service_transport_auth_adc():
)
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
+)
+def test_asset_service_grpc_transport_client_cert_source_for_mtls(transport_class):
+ cred = 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=("https://www.googleapis.com/auth/cloud-platform",),
+ 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_asset_service_host_no_port():
client = AssetServiceClient(
credentials=credentials.AnonymousCredentials(),
@@ -1383,7 +1467,7 @@ def test_asset_service_host_with_port():
def test_asset_service_grpc_transport_channel():
- channel = grpc.insecure_channel("http://localhost/")
+ channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials())
# Check that channel is used if provided.
transport = transports.AssetServiceGrpcTransport(
@@ -1395,7 +1479,7 @@ def test_asset_service_grpc_transport_channel():
def test_asset_service_grpc_asyncio_transport_channel():
- channel = aio.insecure_channel("http://localhost/")
+ channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials())
# Check that channel is used if provided.
transport = transports.AssetServiceGrpcAsyncIOTransport(
@@ -1406,6 +1490,8 @@ def test_asset_service_grpc_asyncio_transport_channel():
assert transport._ssl_channel_credentials == None
+# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are
+# removed from grpc/grpc_asyncio transport constructor.
@pytest.mark.parametrize(
"transport_class",
[transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
@@ -1415,7 +1501,7 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_
"grpc.ssl_channel_credentials", autospec=True
) as grpc_ssl_channel_cred:
with mock.patch.object(
- transport_class, "create_channel", autospec=True
+ transport_class, "create_channel"
) as grpc_create_channel:
mock_ssl_cred = mock.Mock()
grpc_ssl_channel_cred.return_value = mock_ssl_cred
@@ -1453,6 +1539,8 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_
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.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
@@ -1465,7 +1553,7 @@ def test_asset_service_transport_channel_mtls_with_adc(transport_class):
ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
):
with mock.patch.object(
- transport_class, "create_channel", autospec=True
+ transport_class, "create_channel"
) as grpc_create_channel:
mock_grpc_channel = mock.Mock()
grpc_create_channel.return_value = mock_grpc_channel
diff --git a/tests/unit/gapic/asset_v1p2beta1/__init__.py b/tests/unit/gapic/asset_v1p2beta1/__init__.py
index 8b137891..42ffdf2b 100644
--- a/tests/unit/gapic/asset_v1p2beta1/__init__.py
+++ b/tests/unit/gapic/asset_v1p2beta1/__init__.py
@@ -1 +1,16 @@
+# -*- 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/tests/unit/gapic/asset_v1p2beta1/test_asset_service.py b/tests/unit/gapic/asset_v1p2beta1/test_asset_service.py
index 0bba0cd6..c787be79 100644
--- a/tests/unit/gapic/asset_v1p2beta1/test_asset_service.py
+++ b/tests/unit/gapic/asset_v1p2beta1/test_asset_service.py
@@ -81,7 +81,22 @@ def test__get_default_mtls_endpoint():
assert AssetServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi
-@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient])
+@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient,])
+def test_asset_service_client_from_service_account_info(client_class):
+ creds = credentials.AnonymousCredentials()
+ with mock.patch.object(
+ service_account.Credentials, "from_service_account_info"
+ ) as factory:
+ factory.return_value = creds
+ info = {"valid": True}
+ client = client_class.from_service_account_info(info)
+ assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
+
+ assert client.transport._host == "cloudasset.googleapis.com:443"
+
+
+@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient,])
def test_asset_service_client_from_service_account_file(client_class):
creds = credentials.AnonymousCredentials()
with mock.patch.object(
@@ -90,16 +105,21 @@ def test_asset_service_client_from_service_account_file(client_class):
factory.return_value = creds
client = client_class.from_service_account_file("dummy/file/path.json")
assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
client = client_class.from_service_account_json("dummy/file/path.json")
assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
assert client.transport._host == "cloudasset.googleapis.com:443"
def test_asset_service_client_get_transport_class():
transport = AssetServiceClient.get_transport_class()
- assert transport == transports.AssetServiceGrpcTransport
+ available_transports = [
+ transports.AssetServiceGrpcTransport,
+ ]
+ assert transport in available_transports
transport = AssetServiceClient.get_transport_class("grpc")
assert transport == transports.AssetServiceGrpcTransport
@@ -148,7 +168,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -164,7 +184,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -180,7 +200,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_MTLS_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -208,7 +228,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id="octopus",
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -257,29 +277,25 @@ def test_asset_service_client_mtls_env_auto(
client_cert_source=client_cert_source_callback
)
with mock.patch.object(transport_class, "__init__") as patched:
- ssl_channel_creds = mock.Mock()
- with mock.patch(
- "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
- ):
- patched.return_value = None
- client = client_class(client_options=options)
+ patched.return_value = None
+ client = client_class(client_options=options)
- if use_client_cert_env == "false":
- expected_ssl_channel_creds = None
- expected_host = client.DEFAULT_ENDPOINT
- else:
- expected_ssl_channel_creds = ssl_channel_creds
- expected_host = client.DEFAULT_MTLS_ENDPOINT
+ if use_client_cert_env == "false":
+ expected_client_cert_source = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_client_cert_source = client_cert_source_callback
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=expected_host,
- scopes=None,
- ssl_channel_credentials=expected_ssl_channel_creds,
- quota_project_id=None,
- client_info=transports.base.DEFAULT_CLIENT_INFO,
- )
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ client_cert_source_for_mtls=expected_client_cert_source,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
# Check the case ADC client cert is provided. Whether client cert is used depends on
# GOOGLE_API_USE_CLIENT_CERTIFICATE value.
@@ -288,66 +304,53 @@ def test_asset_service_client_mtls_env_auto(
):
with mock.patch.object(transport_class, "__init__") as patched:
with mock.patch(
- "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ "google.auth.transport.mtls.has_default_client_cert_source",
+ return_value=True,
):
with mock.patch(
- "google.auth.transport.grpc.SslCredentials.is_mtls",
- new_callable=mock.PropertyMock,
- ) as is_mtls_mock:
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.ssl_credentials",
- new_callable=mock.PropertyMock,
- ) as ssl_credentials_mock:
- if use_client_cert_env == "false":
- is_mtls_mock.return_value = False
- ssl_credentials_mock.return_value = None
- expected_host = client.DEFAULT_ENDPOINT
- expected_ssl_channel_creds = None
- else:
- is_mtls_mock.return_value = True
- ssl_credentials_mock.return_value = mock.Mock()
- expected_host = client.DEFAULT_MTLS_ENDPOINT
- expected_ssl_channel_creds = (
- ssl_credentials_mock.return_value
- )
-
- patched.return_value = None
- client = client_class()
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=expected_host,
- scopes=None,
- ssl_channel_credentials=expected_ssl_channel_creds,
- quota_project_id=None,
- client_info=transports.base.DEFAULT_CLIENT_INFO,
- )
+ "google.auth.transport.mtls.default_client_cert_source",
+ return_value=client_cert_source_callback,
+ ):
+ if use_client_cert_env == "false":
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_client_cert_source = None
+ else:
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_client_cert_source = client_cert_source_callback
- # Check the case client_cert_source and ADC client cert are not provided.
- with mock.patch.dict(
- os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
- ):
- with mock.patch.object(transport_class, "__init__") as patched:
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
- ):
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.is_mtls",
- new_callable=mock.PropertyMock,
- ) as is_mtls_mock:
- is_mtls_mock.return_value = False
patched.return_value = None
client = client_class()
patched.assert_called_once_with(
credentials=None,
credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
+ host=expected_host,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=expected_client_cert_source,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.mtls.has_default_client_cert_source",
+ return_value=False,
+ ):
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ client_cert_source_for_mtls=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
@pytest.mark.parametrize(
"client_class,transport_class,transport_name",
@@ -373,7 +376,7 @@ def test_asset_service_client_client_options_scopes(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=["1", "2"],
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -403,7 +406,7 @@ def test_asset_service_client_client_options_credentials_file(
credentials_file="credentials.json",
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -420,7 +423,7 @@ def test_asset_service_client_client_options_from_dict():
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -472,6 +475,22 @@ def test_create_feed_from_dict():
test_create_feed(request_type=dict)
+def test_create_feed_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.create_feed), "__call__") as call:
+ client.create_feed()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.CreateFeedRequest()
+
+
@pytest.mark.asyncio
async def test_create_feed_async(
transport: str = "grpc_asyncio", request_type=asset_service.CreateFeedRequest
@@ -679,6 +698,22 @@ def test_get_feed_from_dict():
test_get_feed(request_type=dict)
+def test_get_feed_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.get_feed), "__call__") as call:
+ client.get_feed()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.GetFeedRequest()
+
+
@pytest.mark.asyncio
async def test_get_feed_async(
transport: str = "grpc_asyncio", request_type=asset_service.GetFeedRequest
@@ -875,6 +910,22 @@ def test_list_feeds_from_dict():
test_list_feeds(request_type=dict)
+def test_list_feeds_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.list_feeds), "__call__") as call:
+ client.list_feeds()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.ListFeedsRequest()
+
+
@pytest.mark.asyncio
async def test_list_feeds_async(
transport: str = "grpc_asyncio", request_type=asset_service.ListFeedsRequest
@@ -1075,6 +1126,22 @@ def test_update_feed_from_dict():
test_update_feed(request_type=dict)
+def test_update_feed_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.update_feed), "__call__") as call:
+ client.update_feed()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.UpdateFeedRequest()
+
+
@pytest.mark.asyncio
async def test_update_feed_async(
transport: str = "grpc_asyncio", request_type=asset_service.UpdateFeedRequest
@@ -1272,6 +1339,22 @@ def test_delete_feed_from_dict():
test_delete_feed(request_type=dict)
+def test_delete_feed_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.delete_feed), "__call__") as call:
+ client.delete_feed()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.DeleteFeedRequest()
+
+
@pytest.mark.asyncio
async def test_delete_feed_async(
transport: str = "grpc_asyncio", request_type=asset_service.DeleteFeedRequest
@@ -1476,7 +1559,10 @@ def test_transport_get_channel():
@pytest.mark.parametrize(
"transport_class",
- [transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
+ [
+ transports.AssetServiceGrpcTransport,
+ transports.AssetServiceGrpcAsyncIOTransport,
+ ],
)
def test_transport_adc(transport_class):
# Test default credentials are used if not provided.
@@ -1580,6 +1666,48 @@ def test_asset_service_transport_auth_adc():
)
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
+)
+def test_asset_service_grpc_transport_client_cert_source_for_mtls(transport_class):
+ cred = 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=("https://www.googleapis.com/auth/cloud-platform",),
+ 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_asset_service_host_no_port():
client = AssetServiceClient(
credentials=credentials.AnonymousCredentials(),
@@ -1601,7 +1729,7 @@ def test_asset_service_host_with_port():
def test_asset_service_grpc_transport_channel():
- channel = grpc.insecure_channel("http://localhost/")
+ channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials())
# Check that channel is used if provided.
transport = transports.AssetServiceGrpcTransport(
@@ -1613,7 +1741,7 @@ def test_asset_service_grpc_transport_channel():
def test_asset_service_grpc_asyncio_transport_channel():
- channel = aio.insecure_channel("http://localhost/")
+ channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials())
# Check that channel is used if provided.
transport = transports.AssetServiceGrpcAsyncIOTransport(
@@ -1624,6 +1752,8 @@ def test_asset_service_grpc_asyncio_transport_channel():
assert transport._ssl_channel_credentials == None
+# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are
+# removed from grpc/grpc_asyncio transport constructor.
@pytest.mark.parametrize(
"transport_class",
[transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
@@ -1633,7 +1763,7 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_
"grpc.ssl_channel_credentials", autospec=True
) as grpc_ssl_channel_cred:
with mock.patch.object(
- transport_class, "create_channel", autospec=True
+ transport_class, "create_channel"
) as grpc_create_channel:
mock_ssl_cred = mock.Mock()
grpc_ssl_channel_cred.return_value = mock_ssl_cred
@@ -1671,6 +1801,8 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_
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.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
@@ -1683,7 +1815,7 @@ def test_asset_service_transport_channel_mtls_with_adc(transport_class):
ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
):
with mock.patch.object(
- transport_class, "create_channel", autospec=True
+ transport_class, "create_channel"
) as grpc_create_channel:
mock_grpc_channel = mock.Mock()
grpc_create_channel.return_value = mock_grpc_channel
diff --git a/tests/unit/gapic/asset_v1p4beta1/__init__.py b/tests/unit/gapic/asset_v1p4beta1/__init__.py
index 8b137891..42ffdf2b 100644
--- a/tests/unit/gapic/asset_v1p4beta1/__init__.py
+++ b/tests/unit/gapic/asset_v1p4beta1/__init__.py
@@ -1 +1,16 @@
+# -*- 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/tests/unit/gapic/asset_v1p4beta1/test_asset_service.py b/tests/unit/gapic/asset_v1p4beta1/test_asset_service.py
index abc1823f..a53b106c 100644
--- a/tests/unit/gapic/asset_v1p4beta1/test_asset_service.py
+++ b/tests/unit/gapic/asset_v1p4beta1/test_asset_service.py
@@ -86,7 +86,22 @@ def test__get_default_mtls_endpoint():
assert AssetServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi
-@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient])
+@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient,])
+def test_asset_service_client_from_service_account_info(client_class):
+ creds = credentials.AnonymousCredentials()
+ with mock.patch.object(
+ service_account.Credentials, "from_service_account_info"
+ ) as factory:
+ factory.return_value = creds
+ info = {"valid": True}
+ client = client_class.from_service_account_info(info)
+ assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
+
+ assert client.transport._host == "cloudasset.googleapis.com:443"
+
+
+@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient,])
def test_asset_service_client_from_service_account_file(client_class):
creds = credentials.AnonymousCredentials()
with mock.patch.object(
@@ -95,16 +110,21 @@ def test_asset_service_client_from_service_account_file(client_class):
factory.return_value = creds
client = client_class.from_service_account_file("dummy/file/path.json")
assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
client = client_class.from_service_account_json("dummy/file/path.json")
assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
assert client.transport._host == "cloudasset.googleapis.com:443"
def test_asset_service_client_get_transport_class():
transport = AssetServiceClient.get_transport_class()
- assert transport == transports.AssetServiceGrpcTransport
+ available_transports = [
+ transports.AssetServiceGrpcTransport,
+ ]
+ assert transport in available_transports
transport = AssetServiceClient.get_transport_class("grpc")
assert transport == transports.AssetServiceGrpcTransport
@@ -153,7 +173,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -169,7 +189,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -185,7 +205,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_MTLS_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -213,7 +233,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id="octopus",
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -262,29 +282,25 @@ def test_asset_service_client_mtls_env_auto(
client_cert_source=client_cert_source_callback
)
with mock.patch.object(transport_class, "__init__") as patched:
- ssl_channel_creds = mock.Mock()
- with mock.patch(
- "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
- ):
- patched.return_value = None
- client = client_class(client_options=options)
+ patched.return_value = None
+ client = client_class(client_options=options)
- if use_client_cert_env == "false":
- expected_ssl_channel_creds = None
- expected_host = client.DEFAULT_ENDPOINT
- else:
- expected_ssl_channel_creds = ssl_channel_creds
- expected_host = client.DEFAULT_MTLS_ENDPOINT
+ if use_client_cert_env == "false":
+ expected_client_cert_source = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_client_cert_source = client_cert_source_callback
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=expected_host,
- scopes=None,
- ssl_channel_credentials=expected_ssl_channel_creds,
- quota_project_id=None,
- client_info=transports.base.DEFAULT_CLIENT_INFO,
- )
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ client_cert_source_for_mtls=expected_client_cert_source,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
# Check the case ADC client cert is provided. Whether client cert is used depends on
# GOOGLE_API_USE_CLIENT_CERTIFICATE value.
@@ -293,66 +309,53 @@ def test_asset_service_client_mtls_env_auto(
):
with mock.patch.object(transport_class, "__init__") as patched:
with mock.patch(
- "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ "google.auth.transport.mtls.has_default_client_cert_source",
+ return_value=True,
):
with mock.patch(
- "google.auth.transport.grpc.SslCredentials.is_mtls",
- new_callable=mock.PropertyMock,
- ) as is_mtls_mock:
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.ssl_credentials",
- new_callable=mock.PropertyMock,
- ) as ssl_credentials_mock:
- if use_client_cert_env == "false":
- is_mtls_mock.return_value = False
- ssl_credentials_mock.return_value = None
- expected_host = client.DEFAULT_ENDPOINT
- expected_ssl_channel_creds = None
- else:
- is_mtls_mock.return_value = True
- ssl_credentials_mock.return_value = mock.Mock()
- expected_host = client.DEFAULT_MTLS_ENDPOINT
- expected_ssl_channel_creds = (
- ssl_credentials_mock.return_value
- )
-
- patched.return_value = None
- client = client_class()
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=expected_host,
- scopes=None,
- ssl_channel_credentials=expected_ssl_channel_creds,
- quota_project_id=None,
- client_info=transports.base.DEFAULT_CLIENT_INFO,
- )
+ "google.auth.transport.mtls.default_client_cert_source",
+ return_value=client_cert_source_callback,
+ ):
+ if use_client_cert_env == "false":
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_client_cert_source = None
+ else:
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_client_cert_source = client_cert_source_callback
- # Check the case client_cert_source and ADC client cert are not provided.
- with mock.patch.dict(
- os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
- ):
- with mock.patch.object(transport_class, "__init__") as patched:
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
- ):
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.is_mtls",
- new_callable=mock.PropertyMock,
- ) as is_mtls_mock:
- is_mtls_mock.return_value = False
patched.return_value = None
client = client_class()
patched.assert_called_once_with(
credentials=None,
credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
+ host=expected_host,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=expected_client_cert_source,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.mtls.has_default_client_cert_source",
+ return_value=False,
+ ):
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ client_cert_source_for_mtls=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
@pytest.mark.parametrize(
"client_class,transport_class,transport_name",
@@ -378,7 +381,7 @@ def test_asset_service_client_client_options_scopes(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=["1", "2"],
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -408,7 +411,7 @@ def test_asset_service_client_client_options_credentials_file(
credentials_file="credentials.json",
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -425,7 +428,7 @@ def test_asset_service_client_client_options_from_dict():
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -468,6 +471,24 @@ def test_analyze_iam_policy_from_dict():
test_analyze_iam_policy(request_type=dict)
+def test_analyze_iam_policy_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client.transport.analyze_iam_policy), "__call__"
+ ) as call:
+ client.analyze_iam_policy()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.AnalyzeIamPolicyRequest()
+
+
@pytest.mark.asyncio
async def test_analyze_iam_policy_async(
transport: str = "grpc_asyncio", request_type=asset_service.AnalyzeIamPolicyRequest
@@ -603,6 +624,24 @@ def test_export_iam_policy_analysis_from_dict():
test_export_iam_policy_analysis(request_type=dict)
+def test_export_iam_policy_analysis_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client.transport.export_iam_policy_analysis), "__call__"
+ ) as call:
+ client.export_iam_policy_analysis()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.ExportIamPolicyAnalysisRequest()
+
+
@pytest.mark.asyncio
async def test_export_iam_policy_analysis_async(
transport: str = "grpc_asyncio",
@@ -759,7 +798,10 @@ def test_transport_get_channel():
@pytest.mark.parametrize(
"transport_class",
- [transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
+ [
+ transports.AssetServiceGrpcTransport,
+ transports.AssetServiceGrpcAsyncIOTransport,
+ ],
)
def test_transport_adc(transport_class):
# Test default credentials are used if not provided.
@@ -865,6 +907,48 @@ def test_asset_service_transport_auth_adc():
)
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
+)
+def test_asset_service_grpc_transport_client_cert_source_for_mtls(transport_class):
+ cred = 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=("https://www.googleapis.com/auth/cloud-platform",),
+ 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_asset_service_host_no_port():
client = AssetServiceClient(
credentials=credentials.AnonymousCredentials(),
@@ -886,7 +970,7 @@ def test_asset_service_host_with_port():
def test_asset_service_grpc_transport_channel():
- channel = grpc.insecure_channel("http://localhost/")
+ channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials())
# Check that channel is used if provided.
transport = transports.AssetServiceGrpcTransport(
@@ -898,7 +982,7 @@ def test_asset_service_grpc_transport_channel():
def test_asset_service_grpc_asyncio_transport_channel():
- channel = aio.insecure_channel("http://localhost/")
+ channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials())
# Check that channel is used if provided.
transport = transports.AssetServiceGrpcAsyncIOTransport(
@@ -909,6 +993,8 @@ def test_asset_service_grpc_asyncio_transport_channel():
assert transport._ssl_channel_credentials == None
+# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are
+# removed from grpc/grpc_asyncio transport constructor.
@pytest.mark.parametrize(
"transport_class",
[transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
@@ -918,7 +1004,7 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_
"grpc.ssl_channel_credentials", autospec=True
) as grpc_ssl_channel_cred:
with mock.patch.object(
- transport_class, "create_channel", autospec=True
+ transport_class, "create_channel"
) as grpc_create_channel:
mock_ssl_cred = mock.Mock()
grpc_ssl_channel_cred.return_value = mock_ssl_cred
@@ -956,6 +1042,8 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_
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.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
@@ -968,7 +1056,7 @@ def test_asset_service_transport_channel_mtls_with_adc(transport_class):
ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
):
with mock.patch.object(
- transport_class, "create_channel", autospec=True
+ transport_class, "create_channel"
) as grpc_create_channel:
mock_grpc_channel = mock.Mock()
grpc_create_channel.return_value = mock_grpc_channel
diff --git a/tests/unit/gapic/asset_v1p5beta1/__init__.py b/tests/unit/gapic/asset_v1p5beta1/__init__.py
index 8b137891..42ffdf2b 100644
--- a/tests/unit/gapic/asset_v1p5beta1/__init__.py
+++ b/tests/unit/gapic/asset_v1p5beta1/__init__.py
@@ -1 +1,16 @@
+# -*- 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/tests/unit/gapic/asset_v1p5beta1/test_asset_service.py b/tests/unit/gapic/asset_v1p5beta1/test_asset_service.py
index 37d63e8e..8d56a60f 100644
--- a/tests/unit/gapic/asset_v1p5beta1/test_asset_service.py
+++ b/tests/unit/gapic/asset_v1p5beta1/test_asset_service.py
@@ -83,7 +83,22 @@ def test__get_default_mtls_endpoint():
assert AssetServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi
-@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient])
+@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient,])
+def test_asset_service_client_from_service_account_info(client_class):
+ creds = credentials.AnonymousCredentials()
+ with mock.patch.object(
+ service_account.Credentials, "from_service_account_info"
+ ) as factory:
+ factory.return_value = creds
+ info = {"valid": True}
+ client = client_class.from_service_account_info(info)
+ assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
+
+ assert client.transport._host == "cloudasset.googleapis.com:443"
+
+
+@pytest.mark.parametrize("client_class", [AssetServiceClient, AssetServiceAsyncClient,])
def test_asset_service_client_from_service_account_file(client_class):
creds = credentials.AnonymousCredentials()
with mock.patch.object(
@@ -92,16 +107,21 @@ def test_asset_service_client_from_service_account_file(client_class):
factory.return_value = creds
client = client_class.from_service_account_file("dummy/file/path.json")
assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
client = client_class.from_service_account_json("dummy/file/path.json")
assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
assert client.transport._host == "cloudasset.googleapis.com:443"
def test_asset_service_client_get_transport_class():
transport = AssetServiceClient.get_transport_class()
- assert transport == transports.AssetServiceGrpcTransport
+ available_transports = [
+ transports.AssetServiceGrpcTransport,
+ ]
+ assert transport in available_transports
transport = AssetServiceClient.get_transport_class("grpc")
assert transport == transports.AssetServiceGrpcTransport
@@ -150,7 +170,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -166,7 +186,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -182,7 +202,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_MTLS_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -210,7 +230,7 @@ def test_asset_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id="octopus",
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -259,29 +279,25 @@ def test_asset_service_client_mtls_env_auto(
client_cert_source=client_cert_source_callback
)
with mock.patch.object(transport_class, "__init__") as patched:
- ssl_channel_creds = mock.Mock()
- with mock.patch(
- "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
- ):
- patched.return_value = None
- client = client_class(client_options=options)
+ patched.return_value = None
+ client = client_class(client_options=options)
- if use_client_cert_env == "false":
- expected_ssl_channel_creds = None
- expected_host = client.DEFAULT_ENDPOINT
- else:
- expected_ssl_channel_creds = ssl_channel_creds
- expected_host = client.DEFAULT_MTLS_ENDPOINT
+ if use_client_cert_env == "false":
+ expected_client_cert_source = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_client_cert_source = client_cert_source_callback
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=expected_host,
- scopes=None,
- ssl_channel_credentials=expected_ssl_channel_creds,
- quota_project_id=None,
- client_info=transports.base.DEFAULT_CLIENT_INFO,
- )
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ client_cert_source_for_mtls=expected_client_cert_source,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
# Check the case ADC client cert is provided. Whether client cert is used depends on
# GOOGLE_API_USE_CLIENT_CERTIFICATE value.
@@ -290,66 +306,53 @@ def test_asset_service_client_mtls_env_auto(
):
with mock.patch.object(transport_class, "__init__") as patched:
with mock.patch(
- "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ "google.auth.transport.mtls.has_default_client_cert_source",
+ return_value=True,
):
with mock.patch(
- "google.auth.transport.grpc.SslCredentials.is_mtls",
- new_callable=mock.PropertyMock,
- ) as is_mtls_mock:
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.ssl_credentials",
- new_callable=mock.PropertyMock,
- ) as ssl_credentials_mock:
- if use_client_cert_env == "false":
- is_mtls_mock.return_value = False
- ssl_credentials_mock.return_value = None
- expected_host = client.DEFAULT_ENDPOINT
- expected_ssl_channel_creds = None
- else:
- is_mtls_mock.return_value = True
- ssl_credentials_mock.return_value = mock.Mock()
- expected_host = client.DEFAULT_MTLS_ENDPOINT
- expected_ssl_channel_creds = (
- ssl_credentials_mock.return_value
- )
-
- patched.return_value = None
- client = client_class()
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=expected_host,
- scopes=None,
- ssl_channel_credentials=expected_ssl_channel_creds,
- quota_project_id=None,
- client_info=transports.base.DEFAULT_CLIENT_INFO,
- )
+ "google.auth.transport.mtls.default_client_cert_source",
+ return_value=client_cert_source_callback,
+ ):
+ if use_client_cert_env == "false":
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_client_cert_source = None
+ else:
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_client_cert_source = client_cert_source_callback
- # Check the case client_cert_source and ADC client cert are not provided.
- with mock.patch.dict(
- os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
- ):
- with mock.patch.object(transport_class, "__init__") as patched:
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
- ):
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.is_mtls",
- new_callable=mock.PropertyMock,
- ) as is_mtls_mock:
- is_mtls_mock.return_value = False
patched.return_value = None
client = client_class()
patched.assert_called_once_with(
credentials=None,
credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
+ host=expected_host,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=expected_client_cert_source,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.mtls.has_default_client_cert_source",
+ return_value=False,
+ ):
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ client_cert_source_for_mtls=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
@pytest.mark.parametrize(
"client_class,transport_class,transport_name",
@@ -375,7 +378,7 @@ def test_asset_service_client_client_options_scopes(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=["1", "2"],
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -405,7 +408,7 @@ def test_asset_service_client_client_options_credentials_file(
credentials_file="credentials.json",
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -422,7 +425,7 @@ def test_asset_service_client_client_options_from_dict():
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -465,6 +468,22 @@ def test_list_assets_from_dict():
test_list_assets(request_type=dict)
+def test_list_assets_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 = AssetServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.list_assets), "__call__") as call:
+ client.list_assets()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == asset_service.ListAssetsRequest()
+
+
@pytest.mark.asyncio
async def test_list_assets_async(
transport: str = "grpc_asyncio", request_type=asset_service.ListAssetsRequest
@@ -724,7 +743,10 @@ def test_transport_get_channel():
@pytest.mark.parametrize(
"transport_class",
- [transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
+ [
+ transports.AssetServiceGrpcTransport,
+ transports.AssetServiceGrpcAsyncIOTransport,
+ ],
)
def test_transport_adc(transport_class):
# Test default credentials are used if not provided.
@@ -822,6 +844,48 @@ def test_asset_service_transport_auth_adc():
)
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
+)
+def test_asset_service_grpc_transport_client_cert_source_for_mtls(transport_class):
+ cred = 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=("https://www.googleapis.com/auth/cloud-platform",),
+ 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_asset_service_host_no_port():
client = AssetServiceClient(
credentials=credentials.AnonymousCredentials(),
@@ -843,7 +907,7 @@ def test_asset_service_host_with_port():
def test_asset_service_grpc_transport_channel():
- channel = grpc.insecure_channel("http://localhost/")
+ channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials())
# Check that channel is used if provided.
transport = transports.AssetServiceGrpcTransport(
@@ -855,7 +919,7 @@ def test_asset_service_grpc_transport_channel():
def test_asset_service_grpc_asyncio_transport_channel():
- channel = aio.insecure_channel("http://localhost/")
+ channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials())
# Check that channel is used if provided.
transport = transports.AssetServiceGrpcAsyncIOTransport(
@@ -866,6 +930,8 @@ def test_asset_service_grpc_asyncio_transport_channel():
assert transport._ssl_channel_credentials == None
+# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are
+# removed from grpc/grpc_asyncio transport constructor.
@pytest.mark.parametrize(
"transport_class",
[transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
@@ -875,7 +941,7 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_
"grpc.ssl_channel_credentials", autospec=True
) as grpc_ssl_channel_cred:
with mock.patch.object(
- transport_class, "create_channel", autospec=True
+ transport_class, "create_channel"
) as grpc_create_channel:
mock_ssl_cred = mock.Mock()
grpc_ssl_channel_cred.return_value = mock_ssl_cred
@@ -913,6 +979,8 @@ def test_asset_service_transport_channel_mtls_with_client_cert_source(transport_
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.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport],
@@ -925,7 +993,7 @@ def test_asset_service_transport_channel_mtls_with_adc(transport_class):
ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
):
with mock.patch.object(
- transport_class, "create_channel", autospec=True
+ transport_class, "create_channel"
) as grpc_create_channel:
mock_grpc_channel = mock.Mock()
grpc_create_channel.return_value = mock_grpc_channel