diff --git a/.coveragerc b/.coveragerc
index 10cb72e8..9a9b9f3e 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/errorreporting/__init__.py, .nox/*
+omit =
+ google/cloud/errorreporting/__init__.py
exclude_lines =
# Re-enable the standard pragma
pragma: NO COVER
@@ -31,4 +15,4 @@ exclude_lines =
# This is added at the module level as a safeguard for if someone
# generates the code and tries to run it without pip installing. This
# makes it virtually impossible to test properly.
- except pkg_resources.DistributionNotFound
\ No newline at end of file
+ except pkg_resources.DistributionNotFound
diff --git a/.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 2a8a5044..4f96711f 100755
--- a/.kokoro/build.sh
+++ b/.kokoro/build.sh
@@ -40,6 +40,16 @@ python3 -m pip uninstall --yes --quiet nox-automation
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
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..320a9129
--- /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-error-reporting
+
+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 dfbbc8de..fefd09c5 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-error-reporting
# 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/CHANGELOG.md b/CHANGELOG.md
index 6cb91480..3e874fd3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,13 @@
[1]: https://pypi.org/project/google-cloud-error-reporting/#history
+### [1.1.2](https://www.github.com/googleapis/python-error-reporting/compare/v1.1.1...v1.1.2) (2021-04-05)
+
+
+### Dependencies
+
+* upgrade sphinx ([#99](https://www.github.com/googleapis/python-error-reporting/issues/99)) ([a118123](https://www.github.com/googleapis/python-error-reporting/commit/a118123cbfe8b5dd2a7ba260631b248c351cb116))
+
### [1.1.1](https://www.github.com/googleapis/python-error-reporting/compare/v1.1.0...v1.1.1) (2021-02-25)
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index c7763dad..e3dee436 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/docs/errorreporting_v1beta1/error_group_service.rst b/docs/errorreporting_v1beta1/error_group_service.rst
new file mode 100644
index 00000000..dd213525
--- /dev/null
+++ b/docs/errorreporting_v1beta1/error_group_service.rst
@@ -0,0 +1,6 @@
+ErrorGroupService
+-----------------------------------
+
+.. automodule:: google.cloud.errorreporting_v1beta1.services.error_group_service
+ :members:
+ :inherited-members:
diff --git a/docs/errorreporting_v1beta1/error_stats_service.rst b/docs/errorreporting_v1beta1/error_stats_service.rst
new file mode 100644
index 00000000..30d29e69
--- /dev/null
+++ b/docs/errorreporting_v1beta1/error_stats_service.rst
@@ -0,0 +1,11 @@
+ErrorStatsService
+-----------------------------------
+
+.. automodule:: google.cloud.errorreporting_v1beta1.services.error_stats_service
+ :members:
+ :inherited-members:
+
+
+.. automodule:: google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers
+ :members:
+ :inherited-members:
diff --git a/docs/errorreporting_v1beta1/report_errors_service.rst b/docs/errorreporting_v1beta1/report_errors_service.rst
new file mode 100644
index 00000000..ccddb8b0
--- /dev/null
+++ b/docs/errorreporting_v1beta1/report_errors_service.rst
@@ -0,0 +1,6 @@
+ReportErrorsService
+-------------------------------------
+
+.. automodule:: google.cloud.errorreporting_v1beta1.services.report_errors_service
+ :members:
+ :inherited-members:
diff --git a/docs/errorreporting_v1beta1/services.rst b/docs/errorreporting_v1beta1/services.rst
index a5ec3b92..e888027f 100644
--- a/docs/errorreporting_v1beta1/services.rst
+++ b/docs/errorreporting_v1beta1/services.rst
@@ -1,12 +1,8 @@
Services for Google Cloud Errorreporting v1beta1 API
====================================================
+.. toctree::
+ :maxdepth: 2
-.. automodule:: google.cloud.errorreporting_v1beta1.services.error_group_service
- :members:
- :inherited-members:
-.. automodule:: google.cloud.errorreporting_v1beta1.services.error_stats_service
- :members:
- :inherited-members:
-.. automodule:: google.cloud.errorreporting_v1beta1.services.report_errors_service
- :members:
- :inherited-members:
+ error_group_service
+ error_stats_service
+ report_errors_service
diff --git a/docs/errorreporting_v1beta1/types.rst b/docs/errorreporting_v1beta1/types.rst
index 08851dbe..179256c7 100644
--- a/docs/errorreporting_v1beta1/types.rst
+++ b/docs/errorreporting_v1beta1/types.rst
@@ -3,4 +3,5 @@ Types for Google Cloud Errorreporting v1beta1 API
.. automodule:: google.cloud.errorreporting_v1beta1.types
:members:
+ :undoc-members:
:show-inheritance:
diff --git a/google/cloud/errorreporting_v1beta1/__init__.py b/google/cloud/errorreporting_v1beta1/__init__.py
index 8db40bd7..56f82962 100644
--- a/google/cloud/errorreporting_v1beta1/__init__.py
+++ b/google/cloud/errorreporting_v1beta1/__init__.py
@@ -22,6 +22,7 @@
from .types.common import ErrorEvent
from .types.common import ErrorGroup
from .types.common import HttpRequestContext
+from .types.common import ResolutionStatus
from .types.common import ServiceContext
from .types.common import SourceLocation
from .types.common import TrackingIssue
@@ -64,6 +65,7 @@
"ReportErrorEventResponse",
"ReportErrorsServiceClient",
"ReportedErrorEvent",
+ "ResolutionStatus",
"ServiceContext",
"ServiceContextFilter",
"SourceLocation",
diff --git a/google/cloud/errorreporting_v1beta1/proto/common.proto b/google/cloud/errorreporting_v1beta1/proto/common.proto
index 7a1d2003..e9bb321e 100644
--- a/google/cloud/errorreporting_v1beta1/proto/common.proto
+++ b/google/cloud/errorreporting_v1beta1/proto/common.proto
@@ -1,4 +1,4 @@
-// Copyright 2019 Google LLC.
+// 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.
@@ -16,9 +16,9 @@ syntax = "proto3";
package google.devtools.clouderrorreporting.v1beta1;
-import "google/api/annotations.proto";
import "google/api/resource.proto";
import "google/protobuf/timestamp.proto";
+import "google/api/annotations.proto";
option cc_enable_arenas = true;
option csharp_namespace = "Google.Cloud.ErrorReporting.V1Beta1";
@@ -37,7 +37,7 @@ message ErrorGroup {
};
// The group resource name.
- // Example: projects/my-project-123/groups/my-groupid
+ // Example: projects/my-project-123/groups/CNSgkpnppqKCUw
string name = 1;
// Group IDs are unique for a given project. If the same kind of error
@@ -46,6 +46,10 @@ message ErrorGroup {
// Associated tracking issues.
repeated TrackingIssue tracking_issues = 3;
+
+ // Error group's resolution status.
+ // An unspecified resolution status will be interpreted as OPEN
+ ResolutionStatus resolution_status = 5;
}
// Information related to tracking the progress on resolving the error.
@@ -169,3 +173,24 @@ message SourceLocation {
// For example, `my.package.MyClass.method` in case of Java.
string function_name = 4;
}
+
+// Resolution status of an error group.
+enum ResolutionStatus {
+ // Status is unknown. When left unspecified in requests, it is treated like
+ // OPEN.
+ RESOLUTION_STATUS_UNSPECIFIED = 0;
+
+ // The error group is not being addressed. This is the default for
+ // new groups. It is also used for errors re-occurring after marked RESOLVED.
+ OPEN = 1;
+
+ // Error Group manually acknowledged, it can have an issue link attached.
+ ACKNOWLEDGED = 2;
+
+ // Error Group manually resolved, more events for this group are not expected
+ // to occur.
+ RESOLVED = 3;
+
+ // The error group is muted and excluded by default on group stats requests.
+ MUTED = 4;
+}
diff --git a/google/cloud/errorreporting_v1beta1/proto/error_group_service.proto b/google/cloud/errorreporting_v1beta1/proto/error_group_service.proto
index 18182729..0104b62d 100644
--- a/google/cloud/errorreporting_v1beta1/proto/error_group_service.proto
+++ b/google/cloud/errorreporting_v1beta1/proto/error_group_service.proto
@@ -1,4 +1,4 @@
-// Copyright 2019 Google LLC.
+// 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.
@@ -11,7 +11,6 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-//
syntax = "proto3";
@@ -58,7 +57,7 @@ service ErrorGroupService {
// A request to return an individual group.
message GetGroupRequest {
- // The group resource name. Written as
+ // Required. The group resource name. Written as
// `projects/{projectID}/groups/{group_name}`. Call
// [`groupStats.list`](https://cloud.google.com/error-reporting/reference/rest/v1beta1/projects.groupStats/list)
// to return a list of groups belonging to this project.
diff --git a/google/cloud/errorreporting_v1beta1/proto/error_stats_service.proto b/google/cloud/errorreporting_v1beta1/proto/error_stats_service.proto
index 0773f488..6c62edd9 100644
--- a/google/cloud/errorreporting_v1beta1/proto/error_stats_service.proto
+++ b/google/cloud/errorreporting_v1beta1/proto/error_stats_service.proto
@@ -1,4 +1,4 @@
-// Copyright 2019 Google LLC.
+// 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.
@@ -11,7 +11,6 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-//
syntax = "proto3";
@@ -68,11 +67,11 @@ service ErrorStatsService {
// Specifies a set of `ErrorGroupStats` to return.
message ListGroupStatsRequest {
// Required. The resource name of the Google Cloud Platform project. Written
- // as projects/
plus the
- // Google Cloud
- // Platform project ID.
+ // as `projects/{projectID}` or `projects/{projectNumber}`, where `{projectID}`
+ // and `{projectNumber}` can be found in the
+ // [Google Cloud Console](https://support.google.com/cloud/answer/6158840).
//
- // Example: projects/my-project-123
.
+ // Examples: `projects/my-project-123`, `projects/5551234`.
string project_name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
@@ -258,9 +257,10 @@ enum ErrorGroupOrder {
// Specifies a set of error events to return.
message ListEventsRequest {
// Required. The resource name of the Google Cloud Platform project. Written
- // as `projects/` plus the
+ // as `projects/{projectID}`, where `{projectID}` is the
// [Google Cloud Platform project
// ID](https://support.google.com/cloud/answer/6158840).
+ //
// Example: `projects/my-project-123`.
string project_name = 1 [
(google.api.field_behavior) = REQUIRED,
@@ -357,9 +357,10 @@ message ServiceContextFilter {
// Deletes all events in the project.
message DeleteEventsRequest {
// Required. The resource name of the Google Cloud Platform project. Written
- // as `projects/` plus the
+ // as `projects/{projectID}`, where `{projectID}` is the
// [Google Cloud Platform project
// ID](https://support.google.com/cloud/answer/6158840).
+ //
// Example: `projects/my-project-123`.
string project_name = 1 [
(google.api.field_behavior) = REQUIRED,
diff --git a/google/cloud/errorreporting_v1beta1/proto/report_errors_service.proto b/google/cloud/errorreporting_v1beta1/proto/report_errors_service.proto
index f46f546d..cd1e5100 100644
--- a/google/cloud/errorreporting_v1beta1/proto/report_errors_service.proto
+++ b/google/cloud/errorreporting_v1beta1/proto/report_errors_service.proto
@@ -1,4 +1,4 @@
-// Copyright 2019 Google LLC.
+// 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.
@@ -11,7 +11,6 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-//
syntax = "proto3";
@@ -38,7 +37,7 @@ service ReportErrorsService {
option (google.api.default_host) = "clouderrorreporting.googleapis.com";
option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform";
- // Report an individual error event.
+ // Report an individual error event and record the event to a log.
//
// This endpoint accepts **either** an OAuth token,
// **or** an [API key](https://support.google.com/cloud/answer/6158862)
@@ -46,7 +45,15 @@ service ReportErrorsService {
// a `key` parameter. For example:
//
// `POST
- // https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456`
+ // https://clouderrorreporting.googleapis.com/v1beta1/{projectName}/events:report?key=123ABC456`
+ //
+ // **Note:** [Error Reporting](/error-reporting) is a global service built
+ // on Cloud Logging and doesn't analyze logs stored
+ // in regional log buckets or logs routed to other Google Cloud projects.
+ //
+ // For more information, see
+ // [Using Error Reporting with regionalized
+ // logs](/error-reporting/docs/regionalization).
rpc ReportErrorEvent(ReportErrorEventRequest) returns (ReportErrorEventResponse) {
option (google.api.http) = {
post: "/v1beta1/{project_name=projects/*}/events:report"
@@ -59,10 +66,11 @@ service ReportErrorsService {
// A request for reporting an individual error event.
message ReportErrorEventRequest {
// Required. The resource name of the Google Cloud Platform project. Written
- // as `projects/` plus the
+ // as `projects/{projectId}`, where `{projectId}` is the
// [Google Cloud Platform project
- // ID](https://support.google.com/cloud/answer/6158840). Example:
- // `projects/my-project-123`.
+ // ID](https://support.google.com/cloud/answer/6158840).
+ //
+ // Example: // `projects/my-project-123`.
string project_name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/async_client.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/async_client.py
index 26c03996..e2af4bb2 100644
--- a/google/cloud/errorreporting_v1beta1/services/error_group_service/async_client.py
+++ b/google/cloud/errorreporting_v1beta1/services/error_group_service/async_client.py
@@ -78,7 +78,36 @@ class ErrorGroupServiceAsyncClient:
ErrorGroupServiceClient.parse_common_location_path
)
- from_service_account_file = ErrorGroupServiceClient.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:
+ ErrorGroupServiceAsyncClient: The constructed client.
+ """
+ return ErrorGroupServiceClient.from_service_account_info.__func__(ErrorGroupServiceAsyncClient, 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:
+ ErrorGroupServiceAsyncClient: The constructed client.
+ """
+ return ErrorGroupServiceClient.from_service_account_file.__func__(ErrorGroupServiceAsyncClient, filename, *args, **kwargs) # type: ignore
+
from_service_account_json = from_service_account_file
@property
@@ -154,16 +183,17 @@ async def get_group(
r"""Get the specified group.
Args:
- request (:class:`~.error_group_service.GetGroupRequest`):
+ request (:class:`google.cloud.errorreporting_v1beta1.types.GetGroupRequest`):
The request object. A request to return an individual
group.
group_name (:class:`str`):
- The group resource name. Written as
+ Required. The group resource name. Written as
``projects/{projectID}/groups/{group_name}``. Call
```groupStats.list`` `__
to return a list of groups belonging to this project.
Example: ``projects/my-project-123/groups/my-group``
+
This corresponds to the ``group_name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -175,7 +205,7 @@ async def get_group(
sent along with the request as metadata.
Returns:
- ~.common.ErrorGroup:
+ google.cloud.errorreporting_v1beta1.types.ErrorGroup:
Description of a group of similar
error events.
@@ -233,12 +263,13 @@ async def update_group(
Fails if the group does not exist.
Args:
- request (:class:`~.error_group_service.UpdateGroupRequest`):
+ request (:class:`google.cloud.errorreporting_v1beta1.types.UpdateGroupRequest`):
The request object. A request to replace the existing
data for the given group.
- group (:class:`~.common.ErrorGroup`):
+ group (:class:`google.cloud.errorreporting_v1beta1.types.ErrorGroup`):
Required. The group which replaces
the resource on the server.
+
This corresponds to the ``group`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -250,7 +281,7 @@ async def update_group(
sent along with the request as metadata.
Returns:
- ~.common.ErrorGroup:
+ google.cloud.errorreporting_v1beta1.types.ErrorGroup:
Description of a group of similar
error events.
diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/client.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/client.py
index d1656df2..db374a93 100644
--- a/google/cloud/errorreporting_v1beta1/services/error_group_service/client.py
+++ b/google/cloud/errorreporting_v1beta1/services/error_group_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:
+ ErrorGroupServiceClient: 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.
+ ErrorGroupServiceClient: The constructed client.
"""
credentials = service_account.Credentials.from_service_account_file(filename)
kwargs["credentials"] = credentials
@@ -227,10 +243,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, ~.ErrorGroupServiceTransport]): The
+ transport (Union[str, ErrorGroupServiceTransport]): 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
@@ -266,21 +282,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:
@@ -323,7 +335,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,
)
@@ -340,16 +352,17 @@ def get_group(
r"""Get the specified group.
Args:
- request (:class:`~.error_group_service.GetGroupRequest`):
+ request (google.cloud.errorreporting_v1beta1.types.GetGroupRequest):
The request object. A request to return an individual
group.
- group_name (:class:`str`):
- The group resource name. Written as
+ group_name (str):
+ Required. The group resource name. Written as
``projects/{projectID}/groups/{group_name}``. Call
```groupStats.list`` `__
to return a list of groups belonging to this project.
Example: ``projects/my-project-123/groups/my-group``
+
This corresponds to the ``group_name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -361,7 +374,7 @@ def get_group(
sent along with the request as metadata.
Returns:
- ~.common.ErrorGroup:
+ google.cloud.errorreporting_v1beta1.types.ErrorGroup:
Description of a group of similar
error events.
@@ -420,12 +433,13 @@ def update_group(
Fails if the group does not exist.
Args:
- request (:class:`~.error_group_service.UpdateGroupRequest`):
+ request (google.cloud.errorreporting_v1beta1.types.UpdateGroupRequest):
The request object. A request to replace the existing
data for the given group.
- group (:class:`~.common.ErrorGroup`):
+ group (google.cloud.errorreporting_v1beta1.types.ErrorGroup):
Required. The group which replaces
the resource on the server.
+
This corresponds to the ``group`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -437,7 +451,7 @@ def update_group(
sent along with the request as metadata.
Returns:
- ~.common.ErrorGroup:
+ google.cloud.errorreporting_v1beta1.types.ErrorGroup:
Description of a group of similar
error events.
diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/base.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/base.py
index 794cf769..45260605 100644
--- a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/base.py
+++ b/google/cloud/errorreporting_v1beta1/services/error_group_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 = {
diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc.py
index 102cdd39..8514d3d7 100644
--- a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc.py
+++ b/google/cloud/errorreporting_v1beta1/services/error_group_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/errorreporting_v1beta1/services/error_group_service/transports/grpc_asyncio.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc_asyncio.py
index f6ed3855..d09a346b 100644
--- a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc_asyncio.py
+++ b/google/cloud/errorreporting_v1beta1/services/error_group_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/errorreporting_v1beta1/services/error_stats_service/async_client.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/async_client.py
index 20e91256..ca116141 100644
--- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/async_client.py
+++ b/google/cloud/errorreporting_v1beta1/services/error_stats_service/async_client.py
@@ -81,7 +81,36 @@ class ErrorStatsServiceAsyncClient:
ErrorStatsServiceClient.parse_common_location_path
)
- from_service_account_file = ErrorStatsServiceClient.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:
+ ErrorStatsServiceAsyncClient: The constructed client.
+ """
+ return ErrorStatsServiceClient.from_service_account_info.__func__(ErrorStatsServiceAsyncClient, 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:
+ ErrorStatsServiceAsyncClient: The constructed client.
+ """
+ return ErrorStatsServiceClient.from_service_account_file.__func__(ErrorStatsServiceAsyncClient, filename, *args, **kwargs) # type: ignore
+
from_service_account_json = from_service_account_file
@property
@@ -158,22 +187,23 @@ async def list_group_stats(
r"""Lists the specified groups.
Args:
- request (:class:`~.error_stats_service.ListGroupStatsRequest`):
+ request (:class:`google.cloud.errorreporting_v1beta1.types.ListGroupStatsRequest`):
The request object. Specifies a set of `ErrorGroupStats`
to return.
project_name (:class:`str`):
- Required. The resource name of the
- Google Cloud Platform project. Written
- as projects/
plus the Google
- Cloud Platform project ID.
-
- Example: projects/my-
- project-123
.
+ Required. The resource name of the Google Cloud Platform
+ project. Written as ``projects/{projectID}`` or
+ ``projects/{projectNumber}``, where ``{projectID}`` and
+ ``{projectNumber}`` can be found in the `Google Cloud
+ Console `__.
+
+ Examples: ``projects/my-project-123``,
+ ``projects/5551234``.
+
This corresponds to the ``project_name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- time_range (:class:`~.error_stats_service.QueryTimeRange`):
+ time_range (:class:`google.cloud.errorreporting_v1beta1.types.QueryTimeRange`):
Optional. List data for the given time range. If not
set, a default time range is used. The field
time_range_begin in the response will specify the
@@ -182,6 +212,7 @@ async def list_group_stats(
unless the request contains an explicit group_id list.
If a group_id list is given, also ErrorGroupStats with
zero occurrences are returned.
+
This corresponds to the ``time_range`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -193,7 +224,7 @@ async def list_group_stats(
sent along with the request as metadata.
Returns:
- ~.pagers.ListGroupStatsAsyncPager:
+ google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListGroupStatsAsyncPager:
Contains a set of requested error
group stats.
Iterating over this object will yield
@@ -262,21 +293,24 @@ async def list_events(
r"""Lists the specified events.
Args:
- request (:class:`~.error_stats_service.ListEventsRequest`):
+ request (:class:`google.cloud.errorreporting_v1beta1.types.ListEventsRequest`):
The request object. Specifies a set of error events to
return.
project_name (:class:`str`):
Required. The resource name of the Google Cloud Platform
- project. Written as ``projects/`` plus the `Google Cloud
- Platform project
+ project. Written as ``projects/{projectID}``, where
+ ``{projectID}`` is the `Google Cloud Platform project
ID `__.
+
Example: ``projects/my-project-123``.
+
This corresponds to the ``project_name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
group_id (:class:`str`):
Required. The group for which events
shall be returned.
+
This corresponds to the ``group_id`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -288,7 +322,7 @@ async def list_events(
sent along with the request as metadata.
Returns:
- ~.pagers.ListEventsAsyncPager:
+ google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListEventsAsyncPager:
Contains a set of requested error
events.
Iterating over this object will yield
@@ -356,14 +390,16 @@ async def delete_events(
r"""Deletes all error events of a given project.
Args:
- request (:class:`~.error_stats_service.DeleteEventsRequest`):
+ request (:class:`google.cloud.errorreporting_v1beta1.types.DeleteEventsRequest`):
The request object. Deletes all events in the project.
project_name (:class:`str`):
Required. The resource name of the Google Cloud Platform
- project. Written as ``projects/`` plus the `Google Cloud
- Platform project
+ project. Written as ``projects/{projectID}``, where
+ ``{projectID}`` is the `Google Cloud Platform project
ID `__.
+
Example: ``projects/my-project-123``.
+
This corresponds to the ``project_name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -375,7 +411,7 @@ async def delete_events(
sent along with the request as metadata.
Returns:
- ~.error_stats_service.DeleteEventsResponse:
+ google.cloud.errorreporting_v1beta1.types.DeleteEventsResponse:
Response message for deleting error
events.
diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/client.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/client.py
index f04fbfef..7178412c 100644
--- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/client.py
+++ b/google/cloud/errorreporting_v1beta1/services/error_stats_service/client.py
@@ -115,6 +115,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:
+ ErrorStatsServiceClient: 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
@@ -127,7 +143,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.
+ ErrorStatsServiceClient: The constructed client.
"""
credentials = service_account.Credentials.from_service_account_file(filename)
kwargs["credentials"] = credentials
@@ -230,10 +246,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, ~.ErrorStatsServiceTransport]): The
+ transport (Union[str, ErrorStatsServiceTransport]): 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
@@ -269,21 +285,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:
@@ -326,7 +338,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,
)
@@ -344,22 +356,23 @@ def list_group_stats(
r"""Lists the specified groups.
Args:
- request (:class:`~.error_stats_service.ListGroupStatsRequest`):
+ request (google.cloud.errorreporting_v1beta1.types.ListGroupStatsRequest):
The request object. Specifies a set of `ErrorGroupStats`
to return.
- project_name (:class:`str`):
- Required. The resource name of the
- Google Cloud Platform project. Written
- as projects/
plus the Google
- Cloud Platform project ID.
-
- Example: projects/my-
- project-123
.
+ project_name (str):
+ Required. The resource name of the Google Cloud Platform
+ project. Written as ``projects/{projectID}`` or
+ ``projects/{projectNumber}``, where ``{projectID}`` and
+ ``{projectNumber}`` can be found in the `Google Cloud
+ Console `__.
+
+ Examples: ``projects/my-project-123``,
+ ``projects/5551234``.
+
This corresponds to the ``project_name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- time_range (:class:`~.error_stats_service.QueryTimeRange`):
+ time_range (google.cloud.errorreporting_v1beta1.types.QueryTimeRange):
Optional. List data for the given time range. If not
set, a default time range is used. The field
time_range_begin in the response will specify the
@@ -368,6 +381,7 @@ def list_group_stats(
unless the request contains an explicit group_id list.
If a group_id list is given, also ErrorGroupStats with
zero occurrences are returned.
+
This corresponds to the ``time_range`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -379,7 +393,7 @@ def list_group_stats(
sent along with the request as metadata.
Returns:
- ~.pagers.ListGroupStatsPager:
+ google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListGroupStatsPager:
Contains a set of requested error
group stats.
Iterating over this object will yield
@@ -449,21 +463,24 @@ def list_events(
r"""Lists the specified events.
Args:
- request (:class:`~.error_stats_service.ListEventsRequest`):
+ request (google.cloud.errorreporting_v1beta1.types.ListEventsRequest):
The request object. Specifies a set of error events to
return.
- project_name (:class:`str`):
+ project_name (str):
Required. The resource name of the Google Cloud Platform
- project. Written as ``projects/`` plus the `Google Cloud
- Platform project
+ project. Written as ``projects/{projectID}``, where
+ ``{projectID}`` is the `Google Cloud Platform project
ID `__.
+
Example: ``projects/my-project-123``.
+
This corresponds to the ``project_name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- group_id (:class:`str`):
+ group_id (str):
Required. The group for which events
shall be returned.
+
This corresponds to the ``group_id`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -475,7 +492,7 @@ def list_events(
sent along with the request as metadata.
Returns:
- ~.pagers.ListEventsPager:
+ google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListEventsPager:
Contains a set of requested error
events.
Iterating over this object will yield
@@ -544,14 +561,16 @@ def delete_events(
r"""Deletes all error events of a given project.
Args:
- request (:class:`~.error_stats_service.DeleteEventsRequest`):
+ request (google.cloud.errorreporting_v1beta1.types.DeleteEventsRequest):
The request object. Deletes all events in the project.
- project_name (:class:`str`):
+ project_name (str):
Required. The resource name of the Google Cloud Platform
- project. Written as ``projects/`` plus the `Google Cloud
- Platform project
+ project. Written as ``projects/{projectID}``, where
+ ``{projectID}`` is the `Google Cloud Platform project
ID `__.
+
Example: ``projects/my-project-123``.
+
This corresponds to the ``project_name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -563,7 +582,7 @@ def delete_events(
sent along with the request as metadata.
Returns:
- ~.error_stats_service.DeleteEventsResponse:
+ google.cloud.errorreporting_v1beta1.types.DeleteEventsResponse:
Response message for deleting error
events.
diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/pagers.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/pagers.py
index 02a4faa4..a5d6c02f 100644
--- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/pagers.py
+++ b/google/cloud/errorreporting_v1beta1/services/error_stats_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.errorreporting_v1beta1.types import common
from google.cloud.errorreporting_v1beta1.types import error_stats_service
@@ -25,7 +34,7 @@ class ListGroupStatsPager:
"""A pager for iterating through ``list_group_stats`` requests.
This class thinly wraps an initial
- :class:`~.error_stats_service.ListGroupStatsResponse` object, and
+ :class:`google.cloud.errorreporting_v1beta1.types.ListGroupStatsResponse` object, and
provides an ``__iter__`` method to iterate through its
``error_group_stats`` field.
@@ -34,7 +43,7 @@ class ListGroupStatsPager:
through the ``error_group_stats`` field on the
corresponding responses.
- All the usual :class:`~.error_stats_service.ListGroupStatsResponse`
+ All the usual :class:`google.cloud.errorreporting_v1beta1.types.ListGroupStatsResponse`
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:`~.error_stats_service.ListGroupStatsRequest`):
+ request (google.cloud.errorreporting_v1beta1.types.ListGroupStatsRequest):
The initial request object.
- response (:class:`~.error_stats_service.ListGroupStatsResponse`):
+ response (google.cloud.errorreporting_v1beta1.types.ListGroupStatsResponse):
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 ListGroupStatsAsyncPager:
"""A pager for iterating through ``list_group_stats`` requests.
This class thinly wraps an initial
- :class:`~.error_stats_service.ListGroupStatsResponse` object, and
+ :class:`google.cloud.errorreporting_v1beta1.types.ListGroupStatsResponse` object, and
provides an ``__aiter__`` method to iterate through its
``error_group_stats`` field.
@@ -96,7 +105,7 @@ class ListGroupStatsAsyncPager:
through the ``error_group_stats`` field on the
corresponding responses.
- All the usual :class:`~.error_stats_service.ListGroupStatsResponse`
+ All the usual :class:`google.cloud.errorreporting_v1beta1.types.ListGroupStatsResponse`
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:`~.error_stats_service.ListGroupStatsRequest`):
+ request (google.cloud.errorreporting_v1beta1.types.ListGroupStatsRequest):
The initial request object.
- response (:class:`~.error_stats_service.ListGroupStatsResponse`):
+ response (google.cloud.errorreporting_v1beta1.types.ListGroupStatsResponse):
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 ListEventsPager:
"""A pager for iterating through ``list_events`` requests.
This class thinly wraps an initial
- :class:`~.error_stats_service.ListEventsResponse` object, and
+ :class:`google.cloud.errorreporting_v1beta1.types.ListEventsResponse` object, and
provides an ``__iter__`` method to iterate through its
``error_events`` field.
@@ -162,7 +171,7 @@ class ListEventsPager:
through the ``error_events`` field on the
corresponding responses.
- All the usual :class:`~.error_stats_service.ListEventsResponse`
+ All the usual :class:`google.cloud.errorreporting_v1beta1.types.ListEventsResponse`
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:`~.error_stats_service.ListEventsRequest`):
+ request (google.cloud.errorreporting_v1beta1.types.ListEventsRequest):
The initial request object.
- response (:class:`~.error_stats_service.ListEventsResponse`):
+ response (google.cloud.errorreporting_v1beta1.types.ListEventsResponse):
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 ListEventsAsyncPager:
"""A pager for iterating through ``list_events`` requests.
This class thinly wraps an initial
- :class:`~.error_stats_service.ListEventsResponse` object, and
+ :class:`google.cloud.errorreporting_v1beta1.types.ListEventsResponse` object, and
provides an ``__aiter__`` method to iterate through its
``error_events`` field.
@@ -224,7 +233,7 @@ class ListEventsAsyncPager:
through the ``error_events`` field on the
corresponding responses.
- All the usual :class:`~.error_stats_service.ListEventsResponse`
+ All the usual :class:`google.cloud.errorreporting_v1beta1.types.ListEventsResponse`
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:`~.error_stats_service.ListEventsRequest`):
+ request (google.cloud.errorreporting_v1beta1.types.ListEventsRequest):
The initial request object.
- response (:class:`~.error_stats_service.ListEventsResponse`):
+ response (google.cloud.errorreporting_v1beta1.types.ListEventsResponse):
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/errorreporting_v1beta1/services/error_stats_service/transports/base.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/base.py
index 9ee79c34..18470b15 100644
--- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/base.py
+++ b/google/cloud/errorreporting_v1beta1/services/error_stats_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 = {
diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc.py
index f9595d23..1e033169 100644
--- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc.py
+++ b/google/cloud/errorreporting_v1beta1/services/error_stats_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/errorreporting_v1beta1/services/error_stats_service/transports/grpc_asyncio.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc_asyncio.py
index 4c687c11..402abb49 100644
--- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc_asyncio.py
+++ b/google/cloud/errorreporting_v1beta1/services/error_stats_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/errorreporting_v1beta1/services/report_errors_service/async_client.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/async_client.py
index 3b7c6fcf..61f223b6 100644
--- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/async_client.py
+++ b/google/cloud/errorreporting_v1beta1/services/report_errors_service/async_client.py
@@ -72,7 +72,36 @@ class ReportErrorsServiceAsyncClient:
ReportErrorsServiceClient.parse_common_location_path
)
- from_service_account_file = ReportErrorsServiceClient.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:
+ ReportErrorsServiceAsyncClient: The constructed client.
+ """
+ return ReportErrorsServiceClient.from_service_account_info.__func__(ReportErrorsServiceAsyncClient, 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:
+ ReportErrorsServiceAsyncClient: The constructed client.
+ """
+ return ReportErrorsServiceClient.from_service_account_file.__func__(ReportErrorsServiceAsyncClient, filename, *args, **kwargs) # type: ignore
+
from_service_account_json = from_service_account_file
@property
@@ -147,31 +176,42 @@ async def report_error_event(
timeout: float = None,
metadata: Sequence[Tuple[str, str]] = (),
) -> report_errors_service.ReportErrorEventResponse:
- r"""Report an individual error event.
+ r"""Report an individual error event and record the event to a log.
This endpoint accepts **either** an OAuth token, **or** an `API
key `__ for
authentication. To use an API key, append it to the URL as the
value of a ``key`` parameter. For example:
- ``POST https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456``
+ ``POST https://clouderrorreporting.googleapis.com/v1beta1/{projectName}/events:report?key=123ABC456``
+
+ **Note:** `Error Reporting `__ is a global
+ service built on Cloud Logging and doesn't analyze logs stored
+ in regional log buckets or logs routed to other Google Cloud
+ projects.
+
+ For more information, see `Using Error Reporting with
+ regionalized logs `__.
Args:
- request (:class:`~.report_errors_service.ReportErrorEventRequest`):
+ request (:class:`google.cloud.errorreporting_v1beta1.types.ReportErrorEventRequest`):
The request object. A request for reporting an
individual error event.
project_name (:class:`str`):
Required. The resource name of the Google Cloud Platform
- project. Written as ``projects/`` plus the `Google Cloud
- Platform project
+ project. Written as ``projects/{projectId}``, where
+ ``{projectId}`` is the `Google Cloud Platform project
ID `__.
- Example: ``projects/my-project-123``.
+
+ Example: // ``projects/my-project-123``.
+
This corresponds to the ``project_name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- event (:class:`~.report_errors_service.ReportedErrorEvent`):
+ event (:class:`google.cloud.errorreporting_v1beta1.types.ReportedErrorEvent`):
Required. The error event to be
reported.
+
This corresponds to the ``event`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -183,7 +223,7 @@ async def report_error_event(
sent along with the request as metadata.
Returns:
- ~.report_errors_service.ReportErrorEventResponse:
+ google.cloud.errorreporting_v1beta1.types.ReportErrorEventResponse:
Response for reporting an individual
error event. Data may be added to this
message in the future.
diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py
index b10ecca4..840e449f 100644
--- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py
+++ b/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py
@@ -111,6 +111,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:
+ ReportErrorsServiceClient: 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
@@ -123,7 +139,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.
+ ReportErrorsServiceClient: The constructed client.
"""
credentials = service_account.Credentials.from_service_account_file(filename)
kwargs["credentials"] = credentials
@@ -215,10 +231,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, ~.ReportErrorsServiceTransport]): The
+ transport (Union[str, ReportErrorsServiceTransport]): 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
@@ -254,21 +270,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:
@@ -311,7 +323,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,
)
@@ -326,31 +338,42 @@ def report_error_event(
timeout: float = None,
metadata: Sequence[Tuple[str, str]] = (),
) -> report_errors_service.ReportErrorEventResponse:
- r"""Report an individual error event.
+ r"""Report an individual error event and record the event to a log.
This endpoint accepts **either** an OAuth token, **or** an `API
key `__ for
authentication. To use an API key, append it to the URL as the
value of a ``key`` parameter. For example:
- ``POST https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456``
+ ``POST https://clouderrorreporting.googleapis.com/v1beta1/{projectName}/events:report?key=123ABC456``
+
+ **Note:** `Error Reporting `__ is a global
+ service built on Cloud Logging and doesn't analyze logs stored
+ in regional log buckets or logs routed to other Google Cloud
+ projects.
+
+ For more information, see `Using Error Reporting with
+ regionalized logs `__.
Args:
- request (:class:`~.report_errors_service.ReportErrorEventRequest`):
+ request (google.cloud.errorreporting_v1beta1.types.ReportErrorEventRequest):
The request object. A request for reporting an
individual error event.
- project_name (:class:`str`):
+ project_name (str):
Required. The resource name of the Google Cloud Platform
- project. Written as ``projects/`` plus the `Google Cloud
- Platform project
+ project. Written as ``projects/{projectId}``, where
+ ``{projectId}`` is the `Google Cloud Platform project
ID `__.
- Example: ``projects/my-project-123``.
+
+ Example: // ``projects/my-project-123``.
+
This corresponds to the ``project_name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- event (:class:`~.report_errors_service.ReportedErrorEvent`):
+ event (google.cloud.errorreporting_v1beta1.types.ReportedErrorEvent):
Required. The error event to be
reported.
+
This corresponds to the ``event`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
@@ -362,7 +385,7 @@ def report_error_event(
sent along with the request as metadata.
Returns:
- ~.report_errors_service.ReportErrorEventResponse:
+ google.cloud.errorreporting_v1beta1.types.ReportErrorEventResponse:
Response for reporting an individual
error event. Data may be added to this
message in the future.
diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/base.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/base.py
index f1a66243..4adbb0d1 100644
--- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/base.py
+++ b/google/cloud/errorreporting_v1beta1/services/report_errors_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 = {
diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc.py
index f2c84d92..8ae306d9 100644
--- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc.py
+++ b/google/cloud/errorreporting_v1beta1/services/report_errors_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
+ 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),
@@ -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
@@ -246,14 +230,22 @@ def report_error_event(
]:
r"""Return a callable for the report error event method over gRPC.
- Report an individual error event.
+ Report an individual error event and record the event to a log.
This endpoint accepts **either** an OAuth token, **or** an `API
key `__ for
authentication. To use an API key, append it to the URL as the
value of a ``key`` parameter. For example:
- ``POST https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456``
+ ``POST https://clouderrorreporting.googleapis.com/v1beta1/{projectName}/events:report?key=123ABC456``
+
+ **Note:** `Error Reporting `__ is a global
+ service built on Cloud Logging and doesn't analyze logs stored
+ in regional log buckets or logs routed to other Google Cloud
+ projects.
+
+ For more information, see `Using Error Reporting with
+ regionalized logs `__.
Returns:
Callable[[~.ReportErrorEventRequest],
diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc_asyncio.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc_asyncio.py
index 39465e57..115e2446 100644
--- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc_asyncio.py
+++ b/google/cloud/errorreporting_v1beta1/services/report_errors_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
+ 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),
@@ -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:
@@ -250,14 +234,22 @@ def report_error_event(
]:
r"""Return a callable for the report error event method over gRPC.
- Report an individual error event.
+ Report an individual error event and record the event to a log.
This endpoint accepts **either** an OAuth token, **or** an `API
key `__ for
authentication. To use an API key, append it to the URL as the
value of a ``key`` parameter. For example:
- ``POST https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456``
+ ``POST https://clouderrorreporting.googleapis.com/v1beta1/{projectName}/events:report?key=123ABC456``
+
+ **Note:** `Error Reporting `__ is a global
+ service built on Cloud Logging and doesn't analyze logs stored
+ in regional log buckets or logs routed to other Google Cloud
+ projects.
+
+ For more information, see `Using Error Reporting with
+ regionalized logs `__.
Returns:
Callable[[~.ReportErrorEventRequest],
diff --git a/google/cloud/errorreporting_v1beta1/types/__init__.py b/google/cloud/errorreporting_v1beta1/types/__init__.py
index fc7243be..9cf5a255 100644
--- a/google/cloud/errorreporting_v1beta1/types/__init__.py
+++ b/google/cloud/errorreporting_v1beta1/types/__init__.py
@@ -16,61 +16,63 @@
#
from .common import (
- ErrorGroup,
- TrackingIssue,
- ErrorEvent,
- ServiceContext,
ErrorContext,
+ ErrorEvent,
+ ErrorGroup,
HttpRequestContext,
+ ServiceContext,
SourceLocation,
+ TrackingIssue,
+ ResolutionStatus,
)
from .error_group_service import (
GetGroupRequest,
UpdateGroupRequest,
)
from .error_stats_service import (
- ListGroupStatsRequest,
- ListGroupStatsResponse,
+ DeleteEventsRequest,
+ DeleteEventsResponse,
ErrorGroupStats,
- TimedCount,
ListEventsRequest,
ListEventsResponse,
+ ListGroupStatsRequest,
+ ListGroupStatsResponse,
QueryTimeRange,
ServiceContextFilter,
- DeleteEventsRequest,
- DeleteEventsResponse,
- TimedCountAlignment,
+ TimedCount,
ErrorGroupOrder,
+ TimedCountAlignment,
)
from .report_errors_service import (
+ ReportedErrorEvent,
ReportErrorEventRequest,
ReportErrorEventResponse,
- ReportedErrorEvent,
)
__all__ = (
- "ErrorGroup",
- "TrackingIssue",
- "ErrorEvent",
- "ServiceContext",
"ErrorContext",
+ "ErrorEvent",
+ "ErrorGroup",
"HttpRequestContext",
+ "ServiceContext",
"SourceLocation",
+ "TrackingIssue",
+ "ResolutionStatus",
"GetGroupRequest",
"UpdateGroupRequest",
- "ListGroupStatsRequest",
- "ListGroupStatsResponse",
+ "DeleteEventsRequest",
+ "DeleteEventsResponse",
"ErrorGroupStats",
- "TimedCount",
"ListEventsRequest",
"ListEventsResponse",
+ "ListGroupStatsRequest",
+ "ListGroupStatsResponse",
"QueryTimeRange",
"ServiceContextFilter",
- "DeleteEventsRequest",
- "DeleteEventsResponse",
- "TimedCountAlignment",
+ "TimedCount",
"ErrorGroupOrder",
+ "TimedCountAlignment",
+ "ReportedErrorEvent",
"ReportErrorEventRequest",
"ReportErrorEventResponse",
- "ReportedErrorEvent",
)
diff --git a/google/cloud/errorreporting_v1beta1/types/common.py b/google/cloud/errorreporting_v1beta1/types/common.py
index 779aa453..e0d1a7eb 100644
--- a/google/cloud/errorreporting_v1beta1/types/common.py
+++ b/google/cloud/errorreporting_v1beta1/types/common.py
@@ -24,6 +24,7 @@
__protobuf__ = proto.module(
package="google.devtools.clouderrorreporting.v1beta1",
manifest={
+ "ResolutionStatus",
"ErrorGroup",
"TrackingIssue",
"ErrorEvent",
@@ -35,6 +36,15 @@
)
+class ResolutionStatus(proto.Enum):
+ r"""Resolution status of an error group."""
+ RESOLUTION_STATUS_UNSPECIFIED = 0
+ OPEN = 1
+ ACKNOWLEDGED = 2
+ RESOLVED = 3
+ MUTED = 4
+
+
class ErrorGroup(proto.Message):
r"""Description of a group of similar error events.
@@ -42,14 +52,18 @@ class ErrorGroup(proto.Message):
name (str):
The group resource name.
Example: projects/my-
- project-123/groups/my-groupid
+ project-123/groups/CNSgkpnppqKCUw
group_id (str):
Group IDs are unique for a given project. If
the same kind of error occurs in different
service contexts, it will receive the same group
ID.
- tracking_issues (Sequence[~.common.TrackingIssue]):
+ tracking_issues (Sequence[google.cloud.errorreporting_v1beta1.types.TrackingIssue]):
Associated tracking issues.
+ resolution_status (google.cloud.errorreporting_v1beta1.types.ResolutionStatus):
+ Error group's resolution status.
+ An unspecified resolution status will be
+ interpreted as OPEN
"""
name = proto.Field(proto.STRING, number=1)
@@ -60,6 +74,8 @@ class ErrorGroup(proto.Message):
proto.MESSAGE, number=3, message="TrackingIssue",
)
+ resolution_status = proto.Field(proto.ENUM, number=5, enum="ResolutionStatus",)
+
class TrackingIssue(proto.Message):
r"""Information related to tracking the progress on resolving the
@@ -80,17 +96,17 @@ class ErrorEvent(proto.Message):
system.
Attributes:
- event_time (~.timestamp.Timestamp):
+ event_time (google.protobuf.timestamp_pb2.Timestamp):
Time when the event occurred as provided in
the error report. If the report did not contain
a timestamp, the time the error was received by
the Error Reporting system is used.
- service_context (~.common.ServiceContext):
+ service_context (google.cloud.errorreporting_v1beta1.types.ServiceContext):
The ``ServiceContext`` for which this error was reported.
message (str):
The stack trace that was reported or logged
by the service.
- context (~.common.ErrorContext):
+ context (google.cloud.errorreporting_v1beta1.types.ErrorContext):
Data about the context in which the error
occurred.
"""
@@ -149,7 +165,7 @@ class ErrorContext(proto.Message):
Engine logs.
Attributes:
- http_request (~.common.HttpRequestContext):
+ http_request (google.cloud.errorreporting_v1beta1.types.HttpRequestContext):
The HTTP request which was processed when the
error was triggered.
user (str):
@@ -160,7 +176,7 @@ class ErrorContext(proto.Message):
this case the Error Reporting system will use other data,
such as remote IP address, to distinguish affected users.
See ``affected_users_count`` in ``ErrorGroupStats``.
- report_location (~.common.SourceLocation):
+ report_location (google.cloud.errorreporting_v1beta1.types.SourceLocation):
The location in the source code where the
decision was made to report the error, usually
the place where it was logged. For a logged
diff --git a/google/cloud/errorreporting_v1beta1/types/error_group_service.py b/google/cloud/errorreporting_v1beta1/types/error_group_service.py
index 70aa92a8..e36854b6 100644
--- a/google/cloud/errorreporting_v1beta1/types/error_group_service.py
+++ b/google/cloud/errorreporting_v1beta1/types/error_group_service.py
@@ -32,7 +32,7 @@ class GetGroupRequest(proto.Message):
Attributes:
group_name (str):
- The group resource name. Written as
+ Required. The group resource name. Written as
``projects/{projectID}/groups/{group_name}``. Call
```groupStats.list`` `__
to return a list of groups belonging to this project.
@@ -47,7 +47,7 @@ class UpdateGroupRequest(proto.Message):
r"""A request to replace the existing data for the given group.
Attributes:
- group (~.common.ErrorGroup):
+ group (google.cloud.errorreporting_v1beta1.types.ErrorGroup):
Required. The group which replaces the
resource on the server.
"""
diff --git a/google/cloud/errorreporting_v1beta1/types/error_stats_service.py b/google/cloud/errorreporting_v1beta1/types/error_stats_service.py
index 51a14e89..3973ca04 100644
--- a/google/cloud/errorreporting_v1beta1/types/error_stats_service.py
+++ b/google/cloud/errorreporting_v1beta1/types/error_stats_service.py
@@ -65,23 +65,23 @@ class ListGroupStatsRequest(proto.Message):
Attributes:
project_name (str):
- Required. The resource name of the Google
- Cloud Platform project. Written as
- projects/
plus the Google
- Cloud Platform project ID.
+ Required. The resource name of the Google Cloud Platform
+ project. Written as ``projects/{projectID}`` or
+ ``projects/{projectNumber}``, where ``{projectID}`` and
+ ``{projectNumber}`` can be found in the `Google Cloud
+ Console `__.
- Example: projects/my-project-123
.
+ Examples: ``projects/my-project-123``, ``projects/5551234``.
group_id (Sequence[str]):
Optional. List all
ErrorGroupStats
with these IDs.
- service_filter (~.error_stats_service.ServiceContextFilter):
+ service_filter (google.cloud.errorreporting_v1beta1.types.ServiceContextFilter):
Optional. List only
ErrorGroupStats
which belong to a
service context that matches the filter. Data
for all service contexts is returned if this
field is not specified.
- time_range (~.error_stats_service.QueryTimeRange):
+ time_range (google.cloud.errorreporting_v1beta1.types.QueryTimeRange):
Optional. List data for the given time range. If not set, a
default time range is used. The field time_range_begin in
the response will specify the beginning of this time range.
@@ -89,17 +89,17 @@ class ListGroupStatsRequest(proto.Message):
range are returned, unless the request contains an explicit
group_id list. If a group_id list is given, also
ErrorGroupStats with zero occurrences are returned.
- timed_count_duration (~.duration.Duration):
+ timed_count_duration (google.protobuf.duration_pb2.Duration):
Optional. The preferred duration for a single returned
``TimedCount``. If not set, no timed counts are returned.
- alignment (~.error_stats_service.TimedCountAlignment):
+ alignment (google.cloud.errorreporting_v1beta1.types.TimedCountAlignment):
Optional. The alignment of the timed counts to be returned.
Default is ``ALIGNMENT_EQUAL_AT_END``.
- alignment_time (~.timestamp.Timestamp):
+ alignment_time (google.protobuf.timestamp_pb2.Timestamp):
Optional. Time where the timed counts shall
be aligned if rounded alignment is chosen.
Default is 00:00 UTC.
- order (~.error_stats_service.ErrorGroupOrder):
+ order (google.cloud.errorreporting_v1beta1.types.ErrorGroupOrder):
Optional. The sort order in which the results are returned.
Default is ``COUNT_DESC``.
page_size (int):
@@ -140,7 +140,7 @@ class ListGroupStatsResponse(proto.Message):
r"""Contains a set of requested error group stats.
Attributes:
- error_group_stats (Sequence[~.error_stats_service.ErrorGroupStats]):
+ error_group_stats (Sequence[google.cloud.errorreporting_v1beta1.types.ErrorGroupStats]):
The error group stats which match the given
request.
next_page_token (str):
@@ -148,7 +148,7 @@ class ListGroupStatsResponse(proto.Message):
Pass this token, along with the same query
parameters as the first request, to view the
next page of results.
- time_range_begin (~.timestamp.Timestamp):
+ time_range_begin (google.protobuf.timestamp_pb2.Timestamp):
The timestamp specifies the start time to
which the request was restricted. The start time
is set based on the requested time range. It may
@@ -177,7 +177,7 @@ class ErrorGroupStats(proto.Message):
criteria, such as a given time period and/or service filter.
Attributes:
- group (~.common.ErrorGroup):
+ group (google.cloud.errorreporting_v1beta1.types.ErrorGroup):
Group data that is independent of the filter
criteria.
count (int):
@@ -195,22 +195,22 @@ class ErrorGroupStats(proto.Message):
provided in the error report. If more users are implicitly
affected, such as due to a crash of the whole service, this
is not reflected here.
- timed_counts (Sequence[~.error_stats_service.TimedCount]):
+ timed_counts (Sequence[google.cloud.errorreporting_v1beta1.types.TimedCount]):
Approximate number of occurrences over time.
Timed counts returned by ListGroups are
guaranteed to be:
- Inside the requested time interval
- Non-overlapping, and
- Ordered by ascending time.
- first_seen_time (~.timestamp.Timestamp):
+ first_seen_time (google.protobuf.timestamp_pb2.Timestamp):
Approximate first occurrence that was ever seen for this
group and which matches the given filter criteria, ignoring
the time_range that was specified in the request.
- last_seen_time (~.timestamp.Timestamp):
+ last_seen_time (google.protobuf.timestamp_pb2.Timestamp):
Approximate last occurrence that was ever seen for this
group and which matches the given filter criteria, ignoring
the time_range that was specified in the request.
- affected_services (Sequence[~.common.ServiceContext]):
+ affected_services (Sequence[google.cloud.errorreporting_v1beta1.types.ServiceContext]):
Service contexts with a non-zero error count for the given
filter criteria. This list can be truncated if multiple
services are affected. Refer to ``num_affected_services``
@@ -218,7 +218,7 @@ class ErrorGroupStats(proto.Message):
num_affected_services (int):
The total number of services with a non-zero
error count for the given filter criteria.
- representative (~.common.ErrorEvent):
+ representative (google.cloud.errorreporting_v1beta1.types.ErrorEvent):
An arbitrary event that is chosen as
representative for the whole group. The
representative event is intended to be used as a
@@ -259,10 +259,10 @@ class TimedCount(proto.Message):
count (int):
Approximate number of occurrences in the
given time period.
- start_time (~.timestamp.Timestamp):
+ start_time (google.protobuf.timestamp_pb2.Timestamp):
Start of the time period to which ``count`` refers
(included).
- end_time (~.timestamp.Timestamp):
+ end_time (google.protobuf.timestamp_pb2.Timestamp):
End of the time period to which ``count`` refers (excluded).
"""
@@ -279,19 +279,20 @@ class ListEventsRequest(proto.Message):
Attributes:
project_name (str):
Required. The resource name of the Google Cloud Platform
- project. Written as ``projects/`` plus the `Google Cloud
- Platform project
+ project. Written as ``projects/{projectID}``, where
+ ``{projectID}`` is the `Google Cloud Platform project
ID `__.
+
Example: ``projects/my-project-123``.
group_id (str):
Required. The group for which events shall be
returned.
- service_filter (~.error_stats_service.ServiceContextFilter):
+ service_filter (google.cloud.errorreporting_v1beta1.types.ServiceContextFilter):
Optional. List only ErrorGroups which belong
to a service context that matches the filter.
Data for all service contexts is returned if
this field is not specified.
- time_range (~.error_stats_service.QueryTimeRange):
+ time_range (google.cloud.errorreporting_v1beta1.types.QueryTimeRange):
Optional. List only data for the given time range. If not
set a default time range is used. The field time_range_begin
in the response will specify the beginning of this time
@@ -323,7 +324,7 @@ class ListEventsResponse(proto.Message):
r"""Contains a set of requested error events.
Attributes:
- error_events (Sequence[~.common.ErrorEvent]):
+ error_events (Sequence[google.cloud.errorreporting_v1beta1.types.ErrorEvent]):
The error events which match the given
request.
next_page_token (str):
@@ -331,7 +332,7 @@ class ListEventsResponse(proto.Message):
Pass this token, along with the same query
parameters as the first request, to view the
next page of results.
- time_range_begin (~.timestamp.Timestamp):
+ time_range_begin (google.protobuf.timestamp_pb2.Timestamp):
The timestamp specifies the start time to
which the request was restricted.
"""
@@ -356,7 +357,7 @@ class QueryTimeRange(proto.Message):
durations might be adjusted for lower durations.
Attributes:
- period (~.error_stats_service.QueryTimeRange.Period):
+ period (google.cloud.errorreporting_v1beta1.types.QueryTimeRange.Period):
Restricts the query to the specified time
range.
"""
@@ -404,9 +405,10 @@ class DeleteEventsRequest(proto.Message):
Attributes:
project_name (str):
Required. The resource name of the Google Cloud Platform
- project. Written as ``projects/`` plus the `Google Cloud
- Platform project
+ project. Written as ``projects/{projectID}``, where
+ ``{projectID}`` is the `Google Cloud Platform project
ID `__.
+
Example: ``projects/my-project-123``.
"""
diff --git a/google/cloud/errorreporting_v1beta1/types/report_errors_service.py b/google/cloud/errorreporting_v1beta1/types/report_errors_service.py
index 1a66727b..bdba6ee8 100644
--- a/google/cloud/errorreporting_v1beta1/types/report_errors_service.py
+++ b/google/cloud/errorreporting_v1beta1/types/report_errors_service.py
@@ -38,11 +38,12 @@ class ReportErrorEventRequest(proto.Message):
Attributes:
project_name (str):
Required. The resource name of the Google Cloud Platform
- project. Written as ``projects/`` plus the `Google Cloud
- Platform project
+ project. Written as ``projects/{projectId}``, where
+ ``{projectId}`` is the `Google Cloud Platform project
ID `__.
- Example: ``projects/my-project-123``.
- event (~.report_errors_service.ReportedErrorEvent):
+
+ Example: // ``projects/my-project-123``.
+ event (google.cloud.errorreporting_v1beta1.types.ReportedErrorEvent):
Required. The error event to be reported.
"""
@@ -62,12 +63,12 @@ class ReportedErrorEvent(proto.Message):
system.
Attributes:
- event_time (~.timestamp.Timestamp):
+ event_time (google.protobuf.timestamp_pb2.Timestamp):
Optional. Time when the event occurred.
If not provided, the time when the event was
received by the Error Reporting system will be
used.
- service_context (~.common.ServiceContext):
+ service_context (google.cloud.errorreporting_v1beta1.types.ServiceContext):
Required. The service context in which this
error has occurred.
message (str):
@@ -96,7 +97,7 @@ class ReportedErrorEvent(proto.Message):
```(string)$exception`` `__.
- **Go**: Must be the return value of
```runtime.Stack()`` `__.
- context (~.common.ErrorContext):
+ context (google.cloud.errorreporting_v1beta1.types.ErrorContext):
Optional. A description of the context in
which the error occurred.
"""
diff --git a/noxfile.py b/noxfile.py
index 544b90d7..3f66499f 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,8 @@
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",
@@ -41,6 +44,9 @@
"docs",
]
+# Error if a python version is missing
+nox.options.error_on_missing_interpreters = True
+
@nox.session(python=DEFAULT_PYTHON_VERSION)
def lint(session):
@@ -81,18 +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("asyncmock", "pytest-asyncio", "-c", constraints_path)
- session.install("-e", ".")
+ 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",
@@ -113,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")
@@ -122,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)
@@ -134,18 +149,28 @@ 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", "test_utils")
+ session.install("mock", "pytest", "google-cloud-testutils", "-c", constraints_path)
+ session.install("-e", "test_utils", "-c", constraints_path)
- session.install("-e", ".")
+ 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)
@@ -156,7 +181,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=100")
+ session.run("coverage", "report", "--show-missing", "--fail-under=98")
session.run("coverage", "erase")
@@ -166,7 +191,7 @@ def docs(session):
"""Build the docs for this library."""
session.install("-e", ".")
- session.install("sphinx<3.0.0", "alabaster", "recommonmark")
+ session.install("sphinx", "alabaster", "recommonmark")
shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True)
session.run(
@@ -188,9 +213,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/api/requirements.txt b/samples/snippets/api/requirements.txt
index 1d08c2fb..47f476da 100644
--- a/samples/snippets/api/requirements.txt
+++ b/samples/snippets/api/requirements.txt
@@ -1 +1 @@
-google-cloud-error-reporting==1.1.0
+google-cloud-error-reporting==1.1.1
diff --git a/samples/snippets/fluent_on_compute/requirements.txt b/samples/snippets/fluent_on_compute/requirements.txt
index d1c2863f..693841f6 100644
--- a/samples/snippets/fluent_on_compute/requirements.txt
+++ b/samples/snippets/fluent_on_compute/requirements.txt
@@ -1 +1 @@
-fluent-logger==0.9.6
+fluent-logger==0.10.0
diff --git a/setup.py b/setup.py
index 1a3a2792..859ef21d 100644
--- a/setup.py
+++ b/setup.py
@@ -22,17 +22,16 @@
name = "google-cloud-error-reporting"
description = "Error Reporting API client library"
-version = "1.1.1"
+version = "1.1.2"
# Should be one of:
# 'Development Status :: 3 - Alpha'
# 'Development Status :: 4 - Beta'
# 'Development Status :: 5 - Production/Stable'
release_status = "Development Status :: 4 - Beta"
dependencies = [
- "google-cloud-logging>=1.14.0, <2.2",
- "google-api-core[grpc] >= 1.22.0, < 2.0.0dev",
+ "google-cloud-logging>=1.14.0, <2.4",
+ "google-api-core[grpc] >= 1.22.2, < 2.0.0dev",
"proto-plus >= 1.4.0",
- "libcst >= 0.2.5",
]
extras = {}
diff --git a/synth.metadata b/synth.metadata
index 330ea88c..bba4a1eb 100644
--- a/synth.metadata
+++ b/synth.metadata
@@ -4,29 +4,29 @@
"git": {
"name": ".",
"remote": "https://github.com/googleapis/python-error-reporting.git",
- "sha": "b6887650c28d9fce253ed5894bb2d64a4fedae19"
+ "sha": "86c5c543d2b278c5b93ea26d42ab3e57281dd4f0"
}
},
{
"git": {
"name": "googleapis",
"remote": "https://github.com/googleapis/googleapis.git",
- "sha": "dd372aa22ded7a8ba6f0e03a80e06358a3fa0907",
- "internalRef": "347055288"
+ "sha": "915925089600094e72e4bfa8cf586c170e6b7109",
+ "internalRef": "366152684"
}
},
{
"git": {
"name": "synthtool",
"remote": "https://github.com/googleapis/synthtool.git",
- "sha": "33366574ffb9e11737b3547eb6f020ecae0536e8"
+ "sha": "6d76df2138f8f841e5a5b9ac427f81def520c15f"
}
},
{
"git": {
"name": "synthtool",
"remote": "https://github.com/googleapis/synthtool.git",
- "sha": "33366574ffb9e11737b3547eb6f020ecae0536e8"
+ "sha": "6d76df2138f8f841e5a5b9ac427f81def520c15f"
}
}
],
@@ -42,6 +42,7 @@
}
],
"generatedFiles": [
+ ".coveragerc",
".flake8",
".github/CONTRIBUTING.md",
".github/ISSUE_TEMPLATE/bug_report.md",
@@ -73,16 +74,21 @@
".kokoro/samples/lint/presubmit.cfg",
".kokoro/samples/python3.6/common.cfg",
".kokoro/samples/python3.6/continuous.cfg",
+ ".kokoro/samples/python3.6/periodic-head.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-head.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-head.cfg",
".kokoro/samples/python3.8/periodic.cfg",
".kokoro/samples/python3.8/presubmit.cfg",
+ ".kokoro/test-samples-against-head.sh",
+ ".kokoro/test-samples-impl.sh",
".kokoro/test-samples.sh",
".kokoro/trampoline.sh",
".kokoro/trampoline_v2.sh",
@@ -95,6 +101,9 @@
"docs/_static/custom.css",
"docs/_templates/layout.html",
"docs/conf.py",
+ "docs/errorreporting_v1beta1/error_group_service.rst",
+ "docs/errorreporting_v1beta1/error_stats_service.rst",
+ "docs/errorreporting_v1beta1/report_errors_service.rst",
"docs/errorreporting_v1beta1/services.rst",
"docs/errorreporting_v1beta1/types.rst",
"docs/multiprocessing.rst",
diff --git a/synth.py b/synth.py
index 46a9fe17..5fb57f34 100644
--- a/synth.py
+++ b/synth.py
@@ -37,7 +37,8 @@
templated_files = common.py_library(
samples=True, # set to True only if there are samples
microgenerator=True,
- system_test_dependencies=["test_utils"]
+ system_test_dependencies=["test_utils"],
+ cov_level=98,
)
s.move(templated_files, excludes=[".coveragerc"]) # microgenerator has a good .coveragerc file
@@ -46,8 +47,5 @@
# ----------------------------------------------------------------------------
python.py_samples(skip_readmes=True)
-# TODO(busunkim): Use latest sphinx after microgenerator transition
-s.replace("noxfile.py", """['"]sphinx['"]""", '"sphinx<3.0.0"')
-
s.shell.run(["nox", "-s", "blacken"], hide_output=False)
diff --git a/testing/constraints-3.6.txt b/testing/constraints-3.6.txt
index e88377ad..cf04f5fa 100644
--- a/testing/constraints-3.6.txt
+++ b/testing/constraints-3.6.txt
@@ -6,6 +6,5 @@
# e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev",
# Then this file should have foo==1.14.0
google-cloud-logging==1.14.0
-google-api-core==1.22.0
+google-api-core==1.22.2
proto-plus==1.4.0
-libcst==0.2.5
\ No newline at end of file
diff --git a/tests/unit/gapic/errorreporting_v1beta1/__init__.py b/tests/unit/gapic/errorreporting_v1beta1/__init__.py
index 8b137891..42ffdf2b 100644
--- a/tests/unit/gapic/errorreporting_v1beta1/__init__.py
+++ b/tests/unit/gapic/errorreporting_v1beta1/__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/errorreporting_v1beta1/test_error_group_service.py b/tests/unit/gapic/errorreporting_v1beta1/test_error_group_service.py
index da93c3df..814cefe8 100644
--- a/tests/unit/gapic/errorreporting_v1beta1/test_error_group_service.py
+++ b/tests/unit/gapic/errorreporting_v1beta1/test_error_group_service.py
@@ -90,7 +90,24 @@ def test__get_default_mtls_endpoint():
@pytest.mark.parametrize(
- "client_class", [ErrorGroupServiceClient, ErrorGroupServiceAsyncClient]
+ "client_class", [ErrorGroupServiceClient, ErrorGroupServiceAsyncClient,]
+)
+def test_error_group_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 == "clouderrorreporting.googleapis.com:443"
+
+
+@pytest.mark.parametrize(
+ "client_class", [ErrorGroupServiceClient, ErrorGroupServiceAsyncClient,]
)
def test_error_group_service_client_from_service_account_file(client_class):
creds = credentials.AnonymousCredentials()
@@ -100,16 +117,21 @@ def test_error_group_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 == "clouderrorreporting.googleapis.com:443"
def test_error_group_service_client_get_transport_class():
transport = ErrorGroupServiceClient.get_transport_class()
- assert transport == transports.ErrorGroupServiceGrpcTransport
+ available_transports = [
+ transports.ErrorGroupServiceGrpcTransport,
+ ]
+ assert transport in available_transports
transport = ErrorGroupServiceClient.get_transport_class("grpc")
assert transport == transports.ErrorGroupServiceGrpcTransport
@@ -160,7 +182,7 @@ def test_error_group_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,
)
@@ -176,7 +198,7 @@ def test_error_group_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,
)
@@ -192,7 +214,7 @@ def test_error_group_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,
)
@@ -220,7 +242,7 @@ def test_error_group_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,
)
@@ -281,29 +303,25 @@ def test_error_group_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.
@@ -312,66 +330,53 @@ def test_error_group_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",
@@ -397,7 +402,7 @@ def test_error_group_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,
)
@@ -427,7 +432,7 @@ def test_error_group_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,
)
@@ -446,7 +451,7 @@ def test_error_group_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,7 +472,9 @@ def test_get_group(
with mock.patch.object(type(client.transport.get_group), "__call__") as call:
# Designate an appropriate return value for the call.
call.return_value = common.ErrorGroup(
- name="name_value", group_id="group_id_value",
+ name="name_value",
+ group_id="group_id_value",
+ resolution_status=common.ResolutionStatus.OPEN,
)
response = client.get_group(request)
@@ -486,11 +493,29 @@ def test_get_group(
assert response.group_id == "group_id_value"
+ assert response.resolution_status == common.ResolutionStatus.OPEN
+
def test_get_group_from_dict():
test_get_group(request_type=dict)
+def test_get_group_empty_call():
+ # This test is a coverage failsafe to make sure that totally empty calls,
+ # i.e. request == None and no flattened fields passed, work.
+ client = ErrorGroupServiceClient(
+ 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_group), "__call__") as call:
+ client.get_group()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == error_group_service.GetGroupRequest()
+
+
@pytest.mark.asyncio
async def test_get_group_async(
transport: str = "grpc_asyncio", request_type=error_group_service.GetGroupRequest
@@ -507,7 +532,11 @@ async def test_get_group_async(
with mock.patch.object(type(client.transport.get_group), "__call__") as call:
# Designate an appropriate return value for the call.
call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
- common.ErrorGroup(name="name_value", group_id="group_id_value",)
+ common.ErrorGroup(
+ name="name_value",
+ group_id="group_id_value",
+ resolution_status=common.ResolutionStatus.OPEN,
+ )
)
response = await client.get_group(request)
@@ -525,6 +554,8 @@ async def test_get_group_async(
assert response.group_id == "group_id_value"
+ assert response.resolution_status == common.ResolutionStatus.OPEN
+
@pytest.mark.asyncio
async def test_get_group_async_from_dict():
@@ -666,7 +697,9 @@ def test_update_group(
with mock.patch.object(type(client.transport.update_group), "__call__") as call:
# Designate an appropriate return value for the call.
call.return_value = common.ErrorGroup(
- name="name_value", group_id="group_id_value",
+ name="name_value",
+ group_id="group_id_value",
+ resolution_status=common.ResolutionStatus.OPEN,
)
response = client.update_group(request)
@@ -685,11 +718,29 @@ def test_update_group(
assert response.group_id == "group_id_value"
+ assert response.resolution_status == common.ResolutionStatus.OPEN
+
def test_update_group_from_dict():
test_update_group(request_type=dict)
+def test_update_group_empty_call():
+ # This test is a coverage failsafe to make sure that totally empty calls,
+ # i.e. request == None and no flattened fields passed, work.
+ client = ErrorGroupServiceClient(
+ 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_group), "__call__") as call:
+ client.update_group()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == error_group_service.UpdateGroupRequest()
+
+
@pytest.mark.asyncio
async def test_update_group_async(
transport: str = "grpc_asyncio", request_type=error_group_service.UpdateGroupRequest
@@ -706,7 +757,11 @@ async def test_update_group_async(
with mock.patch.object(type(client.transport.update_group), "__call__") as call:
# Designate an appropriate return value for the call.
call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
- common.ErrorGroup(name="name_value", group_id="group_id_value",)
+ common.ErrorGroup(
+ name="name_value",
+ group_id="group_id_value",
+ resolution_status=common.ResolutionStatus.OPEN,
+ )
)
response = await client.update_group(request)
@@ -724,6 +779,8 @@ async def test_update_group_async(
assert response.group_id == "group_id_value"
+ assert response.resolution_status == common.ResolutionStatus.OPEN
+
@pytest.mark.asyncio
async def test_update_group_async_from_dict():
@@ -1014,6 +1071,53 @@ def test_error_group_service_transport_auth_adc():
)
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.ErrorGroupServiceGrpcTransport,
+ transports.ErrorGroupServiceGrpcAsyncIOTransport,
+ ],
+)
+def test_error_group_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_error_group_service_host_no_port():
client = ErrorGroupServiceClient(
credentials=credentials.AnonymousCredentials(),
@@ -1035,7 +1139,7 @@ def test_error_group_service_host_with_port():
def test_error_group_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.ErrorGroupServiceGrpcTransport(
@@ -1047,7 +1151,7 @@ def test_error_group_service_grpc_transport_channel():
def test_error_group_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.ErrorGroupServiceGrpcAsyncIOTransport(
@@ -1058,6 +1162,8 @@ def test_error_group_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",
[
@@ -1072,7 +1178,7 @@ def test_error_group_service_transport_channel_mtls_with_client_cert_source(
"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
@@ -1110,6 +1216,8 @@ def test_error_group_service_transport_channel_mtls_with_client_cert_source(
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",
[
@@ -1125,7 +1233,7 @@ def test_error_group_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/errorreporting_v1beta1/test_error_stats_service.py b/tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py
index 2ea69420..1966becb 100644
--- a/tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py
+++ b/tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py
@@ -93,7 +93,24 @@ def test__get_default_mtls_endpoint():
@pytest.mark.parametrize(
- "client_class", [ErrorStatsServiceClient, ErrorStatsServiceAsyncClient]
+ "client_class", [ErrorStatsServiceClient, ErrorStatsServiceAsyncClient,]
+)
+def test_error_stats_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 == "clouderrorreporting.googleapis.com:443"
+
+
+@pytest.mark.parametrize(
+ "client_class", [ErrorStatsServiceClient, ErrorStatsServiceAsyncClient,]
)
def test_error_stats_service_client_from_service_account_file(client_class):
creds = credentials.AnonymousCredentials()
@@ -103,16 +120,21 @@ def test_error_stats_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 == "clouderrorreporting.googleapis.com:443"
def test_error_stats_service_client_get_transport_class():
transport = ErrorStatsServiceClient.get_transport_class()
- assert transport == transports.ErrorStatsServiceGrpcTransport
+ available_transports = [
+ transports.ErrorStatsServiceGrpcTransport,
+ ]
+ assert transport in available_transports
transport = ErrorStatsServiceClient.get_transport_class("grpc")
assert transport == transports.ErrorStatsServiceGrpcTransport
@@ -163,7 +185,7 @@ def test_error_stats_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,
)
@@ -179,7 +201,7 @@ def test_error_stats_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,
)
@@ -195,7 +217,7 @@ def test_error_stats_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,
)
@@ -223,7 +245,7 @@ def test_error_stats_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,
)
@@ -284,29 +306,25 @@ def test_error_stats_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.
@@ -315,66 +333,53 @@ def test_error_stats_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",
@@ -400,7 +405,7 @@ def test_error_stats_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,
)
@@ -430,7 +435,7 @@ def test_error_stats_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,
)
@@ -449,7 +454,7 @@ def test_error_stats_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,
)
@@ -492,6 +497,22 @@ def test_list_group_stats_from_dict():
test_list_group_stats(request_type=dict)
+def test_list_group_stats_empty_call():
+ # This test is a coverage failsafe to make sure that totally empty calls,
+ # i.e. request == None and no flattened fields passed, work.
+ client = ErrorStatsServiceClient(
+ 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_group_stats), "__call__") as call:
+ client.list_group_stats()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == error_stats_service.ListGroupStatsRequest()
+
+
@pytest.mark.asyncio
async def test_list_group_stats_async(
transport: str = "grpc_asyncio",
@@ -888,6 +909,22 @@ def test_list_events_from_dict():
test_list_events(request_type=dict)
+def test_list_events_empty_call():
+ # This test is a coverage failsafe to make sure that totally empty calls,
+ # i.e. request == None and no flattened fields passed, work.
+ client = ErrorStatsServiceClient(
+ 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_events), "__call__") as call:
+ client.list_events()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == error_stats_service.ListEventsRequest()
+
+
@pytest.mark.asyncio
async def test_list_events_async(
transport: str = "grpc_asyncio", request_type=error_stats_service.ListEventsRequest
@@ -1247,6 +1284,22 @@ def test_delete_events_from_dict():
test_delete_events(request_type=dict)
+def test_delete_events_empty_call():
+ # This test is a coverage failsafe to make sure that totally empty calls,
+ # i.e. request == None and no flattened fields passed, work.
+ client = ErrorStatsServiceClient(
+ 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_events), "__call__") as call:
+ client.delete_events()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == error_stats_service.DeleteEventsRequest()
+
+
@pytest.mark.asyncio
async def test_delete_events_async(
transport: str = "grpc_asyncio",
@@ -1575,6 +1628,53 @@ def test_error_stats_service_transport_auth_adc():
)
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.ErrorStatsServiceGrpcTransport,
+ transports.ErrorStatsServiceGrpcAsyncIOTransport,
+ ],
+)
+def test_error_stats_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_error_stats_service_host_no_port():
client = ErrorStatsServiceClient(
credentials=credentials.AnonymousCredentials(),
@@ -1596,7 +1696,7 @@ def test_error_stats_service_host_with_port():
def test_error_stats_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.ErrorStatsServiceGrpcTransport(
@@ -1608,7 +1708,7 @@ def test_error_stats_service_grpc_transport_channel():
def test_error_stats_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.ErrorStatsServiceGrpcAsyncIOTransport(
@@ -1619,6 +1719,8 @@ def test_error_stats_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",
[
@@ -1633,7 +1735,7 @@ def test_error_stats_service_transport_channel_mtls_with_client_cert_source(
"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 +1773,8 @@ def test_error_stats_service_transport_channel_mtls_with_client_cert_source(
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",
[
@@ -1686,7 +1790,7 @@ def test_error_stats_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/errorreporting_v1beta1/test_report_errors_service.py b/tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py
index f84d267f..98a83947 100644
--- a/tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py
+++ b/tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py
@@ -93,7 +93,24 @@ def test__get_default_mtls_endpoint():
@pytest.mark.parametrize(
- "client_class", [ReportErrorsServiceClient, ReportErrorsServiceAsyncClient]
+ "client_class", [ReportErrorsServiceClient, ReportErrorsServiceAsyncClient,]
+)
+def test_report_errors_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 == "clouderrorreporting.googleapis.com:443"
+
+
+@pytest.mark.parametrize(
+ "client_class", [ReportErrorsServiceClient, ReportErrorsServiceAsyncClient,]
)
def test_report_errors_service_client_from_service_account_file(client_class):
creds = credentials.AnonymousCredentials()
@@ -103,16 +120,21 @@ def test_report_errors_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 == "clouderrorreporting.googleapis.com:443"
def test_report_errors_service_client_get_transport_class():
transport = ReportErrorsServiceClient.get_transport_class()
- assert transport == transports.ReportErrorsServiceGrpcTransport
+ available_transports = [
+ transports.ReportErrorsServiceGrpcTransport,
+ ]
+ assert transport in available_transports
transport = ReportErrorsServiceClient.get_transport_class("grpc")
assert transport == transports.ReportErrorsServiceGrpcTransport
@@ -167,7 +189,7 @@ def test_report_errors_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,
)
@@ -183,7 +205,7 @@ def test_report_errors_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,
)
@@ -199,7 +221,7 @@ def test_report_errors_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,
)
@@ -227,7 +249,7 @@ def test_report_errors_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,
)
@@ -288,29 +310,25 @@ def test_report_errors_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.
@@ -319,66 +337,53 @@ def test_report_errors_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",
@@ -408,7 +413,7 @@ def test_report_errors_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,
)
@@ -442,7 +447,7 @@ def test_report_errors_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,
)
@@ -461,7 +466,7 @@ def test_report_errors_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,
)
@@ -502,6 +507,24 @@ def test_report_error_event_from_dict():
test_report_error_event(request_type=dict)
+def test_report_error_event_empty_call():
+ # This test is a coverage failsafe to make sure that totally empty calls,
+ # i.e. request == None and no flattened fields passed, work.
+ client = ReportErrorsServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client.transport.report_error_event), "__call__"
+ ) as call:
+ client.report_error_event()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == report_errors_service.ReportErrorEventRequest()
+
+
@pytest.mark.asyncio
async def test_report_error_event_async(
transport: str = "grpc_asyncio",
@@ -860,6 +883,53 @@ def test_report_errors_service_transport_auth_adc():
)
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.ReportErrorsServiceGrpcTransport,
+ transports.ReportErrorsServiceGrpcAsyncIOTransport,
+ ],
+)
+def test_report_errors_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_report_errors_service_host_no_port():
client = ReportErrorsServiceClient(
credentials=credentials.AnonymousCredentials(),
@@ -881,7 +951,7 @@ def test_report_errors_service_host_with_port():
def test_report_errors_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.ReportErrorsServiceGrpcTransport(
@@ -893,7 +963,7 @@ def test_report_errors_service_grpc_transport_channel():
def test_report_errors_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.ReportErrorsServiceGrpcAsyncIOTransport(
@@ -904,6 +974,8 @@ def test_report_errors_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",
[
@@ -918,7 +990,7 @@ def test_report_errors_service_transport_channel_mtls_with_client_cert_source(
"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 +1028,8 @@ def test_report_errors_service_transport_channel_mtls_with_client_cert_source(
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",
[
@@ -971,7 +1045,7 @@ def test_report_errors_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