From e8b4762d289755377acb7c69744a347fbe6651d6 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Wed, 12 Nov 2025 13:44:16 -0500 Subject: [PATCH 01/11] feat: Add support for Python 3.14 (#712) Towards b/375664027 --------- Co-authored-by: Owl Bot --- .github/.OwlBot.lock.yaml | 3 +- .github/sync-repo-settings.yaml | 28 --------- .github/workflows/lint.yml | 2 +- .github/workflows/unittest.yml | 4 +- .kokoro/samples/python3.14/common.cfg | 60 ++++++++++++++++++++ .kokoro/samples/python3.14/continuous.cfg | 6 ++ .kokoro/samples/python3.14/periodic-head.cfg | 11 ++++ .kokoro/samples/python3.14/periodic.cfg | 6 ++ .kokoro/samples/python3.14/presubmit.cfg | 6 ++ CONTRIBUTING.rst | 12 ++-- README.rst | 2 +- noxfile.py | 31 +++++----- owlbot.py | 1 + pytest.ini | 9 +++ setup.py | 3 + testing/constraints-3.14.txt | 0 16 files changed, 131 insertions(+), 53 deletions(-) delete mode 100644 .github/sync-repo-settings.yaml create mode 100644 .kokoro/samples/python3.14/common.cfg create mode 100644 .kokoro/samples/python3.14/continuous.cfg create mode 100644 .kokoro/samples/python3.14/periodic-head.cfg create mode 100644 .kokoro/samples/python3.14/periodic.cfg create mode 100644 .kokoro/samples/python3.14/presubmit.cfg create mode 100644 testing/constraints-3.14.txt diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index c4e82889..c58733d0 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -13,5 +13,4 @@ # limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - digest: sha256:023a21377a2a00008057f99f0118edadc30a19d1636a3fee47189ebec2f3921c -# created: 2025-03-31T16:51:40.130756953Z + digest: sha256:fbbc8db67afd8b7d71bf694c5081a32da0c528eba166fbcffb3b6e56ddf907d5 diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml deleted file mode 100644 index 1ca6d927..00000000 --- a/.github/sync-repo-settings.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# https://github.com/googleapis/repo-automation-bots/tree/main/packages/sync-repo-settings -# Rules for main branch protection -branchProtectionRules: -# Identifies the protection rule pattern. Name of the branch to be protected. -# Defaults to `main` -- pattern: main - requiresCodeOwnerReviews: true - requiresStrictStatusChecks: true - requiredStatusCheckContexts: - - 'Kokoro' - - 'cla/google' - - 'Samples - Lint' - - 'Samples - Python 3.7' - - 'Samples - Python 3.8' - - 'Samples - Python 3.9' - - 'Samples - Python 3.10' - - 'Samples - Python 3.11' - - 'Samples - Python 3.12' - - 'docs' - - 'docfx' - - 'lint' - - 'unit (3.7)' - - 'unit (3.8)' - - 'unit (3.9)' - - 'unit (3.10)' - - 'unit (3.11)' - - 'unit (3.12)' - - 'cover' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4866193a..3ed755f0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -12,7 +12,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.14" - name: Install nox run: | python -m pip install --upgrade setuptools pip wheel diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml index c66b757c..cc6fe2b2 100644 --- a/.github/workflows/unittest.yml +++ b/.github/workflows/unittest.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: - python: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] + python: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] steps: - name: Checkout uses: actions/checkout@v4 @@ -45,7 +45,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.14" - name: Install coverage run: | python -m pip install --upgrade setuptools pip wheel diff --git a/.kokoro/samples/python3.14/common.cfg b/.kokoro/samples/python3.14/common.cfg new file mode 100644 index 00000000..09f706f6 --- /dev/null +++ b/.kokoro/samples/python3.14/common.cfg @@ -0,0 +1,60 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "py-3.14" +} + +# Declare build specific Cloud project. +env_vars: { + key: "BUILD_SPECIFIC_GCLOUD_PROJECT" + value: "python-docs-samples-tests-314" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-error-reporting/.kokoro/test-samples.sh" +} + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" +} + +# Download secrets for samples +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "python-error-reporting/.kokoro/trampoline_v2.sh" + + +############################################# +# this section merged from .kokoro/common_env_vars.cfg using owlbot.py + +env_vars: { + key: "PRODUCT_AREA_LABEL" + value: "observability" +} +env_vars: { + key: "PRODUCT_LABEL" + value: "error-reporting" +} +env_vars: { + key: "LANGUAGE_LABEL" + value: "python" +} + +################################################### + diff --git a/.kokoro/samples/python3.14/continuous.cfg b/.kokoro/samples/python3.14/continuous.cfg new file mode 100644 index 00000000..a1c8d975 --- /dev/null +++ b/.kokoro/samples/python3.14/continuous.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/.kokoro/samples/python3.14/periodic-head.cfg b/.kokoro/samples/python3.14/periodic-head.cfg new file mode 100644 index 00000000..0ab001ca --- /dev/null +++ b/.kokoro/samples/python3.14/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-error-reporting/.kokoro/test-samples-against-head.sh" +} diff --git a/.kokoro/samples/python3.14/periodic.cfg b/.kokoro/samples/python3.14/periodic.cfg new file mode 100644 index 00000000..71cd1e59 --- /dev/null +++ b/.kokoro/samples/python3.14/periodic.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "False" +} diff --git a/.kokoro/samples/python3.14/presubmit.cfg b/.kokoro/samples/python3.14/presubmit.cfg new file mode 100644 index 00000000..a1c8d975 --- /dev/null +++ b/.kokoro/samples/python3.14/presubmit.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 5307292a..222b6e01 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -22,7 +22,7 @@ In order to add a feature: documentation. - The feature must work fully on the following CPython versions: - 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13 on both UNIX and Windows. + 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13 and 3.14 on both UNIX and Windows. - The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should @@ -143,12 +143,12 @@ Running System Tests $ nox -s system # Run a single system test - $ nox -s system-3.8 -- -k + $ nox -s system-3.14 -- -k .. note:: - System tests are only configured to run under Python 3.8. + System tests are only configured to run under Python 3.14. 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 @@ -195,11 +195,11 @@ configure them just like the System Tests. # Run all tests in a folder $ cd samples/snippets - $ nox -s py-3.8 + $ nox -s py-3.14 # Run a single sample test $ cd samples/snippets - $ nox -s py-3.8 -- -k + $ nox -s py-3.14 -- -k ******************************************** Note About ``README`` as it pertains to PyPI @@ -228,6 +228,7 @@ We support: - `Python 3.11`_ - `Python 3.12`_ - `Python 3.13`_ +- `Python 3.14`_ .. _Python 3.7: https://docs.python.org/3.7/ .. _Python 3.8: https://docs.python.org/3.8/ @@ -236,6 +237,7 @@ We support: .. _Python 3.11: https://docs.python.org/3.11/ .. _Python 3.12: https://docs.python.org/3.12/ .. _Python 3.13: https://docs.python.org/3.13/ +.. _Python 3.14: https://docs.python.org/3.14/ Supported versions can be found in our ``noxfile.py`` `config`_. diff --git a/README.rst b/README.rst index a1b9e25e..7a401641 100644 --- a/README.rst +++ b/README.rst @@ -61,7 +61,7 @@ Supported Python Versions Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of Python. -Python >= 3.7 +Python >= 3.7, including 3.14 .. _active: https://devguide.python.org/devcycle/#in-development-main-branch .. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches diff --git a/noxfile.py b/noxfile.py index bc66951c..35c5330b 100644 --- a/noxfile.py +++ b/noxfile.py @@ -32,7 +32,7 @@ ISORT_VERSION = "isort==5.11.0" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] -DEFAULT_PYTHON_VERSION = "3.8" +DEFAULT_PYTHON_VERSION = "3.14" UNIT_TEST_PYTHON_VERSIONS: List[str] = [ "3.7", @@ -42,6 +42,7 @@ "3.11", "3.12", "3.13", + "3.14", ] UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", @@ -56,7 +57,7 @@ UNIT_TEST_EXTRAS: List[str] = [] UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} -SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.8"] +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.14"] SYSTEM_TEST_STANDARD_DEPENDENCIES: List[str] = [ "mock", "pytest", @@ -71,15 +72,7 @@ CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() nox.options.sessions = [ - "unit", "system", - "cover", - "lint", - "lint_setup_py", - "blacken", - "docs", - "docfx", - "format", ] # Error if a python version is missing @@ -135,7 +128,7 @@ def format(session): @nox.session(python=DEFAULT_PYTHON_VERSION) def lint_setup_py(session): """Verify that setup.py is valid (including RST check).""" - session.install("docutils", "pygments") + session.install("docutils", "pygments", "setuptools") session.run("python", "setup.py", "check", "--restructuredtext", "--strict") @@ -175,7 +168,12 @@ def install_unittest_dependencies(session, *constraints): def unit(session, protobuf_implementation): # Install all test dependencies, then install this package in-place. - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + if protobuf_implementation == "cpp" and session.python in ( + "3.11", + "3.12", + "3.13", + "3.14", + ): session.skip("cpp implementation is not supported in python 3.11+") constraints_path = str( @@ -375,7 +373,7 @@ def docfx(session): ) -@nox.session(python="3.13") +@nox.session(python=DEFAULT_PYTHON_VERSION) @nox.parametrize( "protobuf_implementation", ["python", "upb", "cpp"], @@ -383,7 +381,12 @@ def docfx(session): def prerelease_deps(session, protobuf_implementation): """Run all tests with prerelease versions of dependencies installed.""" - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + if protobuf_implementation == "cpp" and session.python in ( + "3.11", + "3.12", + "3.13", + "3.14", + ): session.skip("cpp implementation is not supported in python 3.11+") # Install all dependencies diff --git a/owlbot.py b/owlbot.py index 0f851388..c45fc6bf 100644 --- a/owlbot.py +++ b/owlbot.py @@ -56,6 +56,7 @@ cov_level=100, microgenerator=True, versions=gcp.common.detect_versions(path="./google", default_first=True), + default_python_version="3.14" ) s.move( templated_files, diff --git a/pytest.ini b/pytest.ini index 4166e729..4b0c3a75 100644 --- a/pytest.ini +++ b/pytest.ini @@ -13,3 +13,12 @@ filterwarnings = ignore:get_mtls_endpoint_and_cert_source is deprecated.:DeprecationWarning # Remove warning once the minium supported version of google-cloud-logging is 2.x.x ignore:.*Create unlinked descriptors is going to go away. Please use get/find descriptors from generated code or query the descriptor_pool.*:DeprecationWarning + # Remove tests for `credentials_file` once support for `credentials_file` is removed in `google-auth` + ignore:The `credentials_file` argument is deprecated because of a potential security risk:DeprecationWarning + # Remove after support for Python 3.8 is dropped + ignore:You are using a non-supported Python version \(3\.8:DeprecationWarning + ignore:You are using a non-supported Python version \(3\.8:FutureWarning + # Remove after support for Python 3.9 is dropped + ignore:You are using a Python version \(3\.9:FutureWarning + # Remove after support for Python 3.10 is dropped + ignore:.*You are using a Python version \(3\.10:FutureWarning diff --git a/setup.py b/setup.py index 530e3c7f..c80d2b25 100644 --- a/setup.py +++ b/setup.py @@ -43,6 +43,8 @@ # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "google-api-core[grpc] >= 1.34.0, <3.0.0,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", + "grpcio >= 1.33.2, < 2.0.0", + "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", "proto-plus >= 1.22.0, <2.0.0", "proto-plus >= 1.22.2, <2.0.0; python_version>='3.11'", "proto-plus >= 1.25.0, <2.0.0dev; python_version>='3.13'", @@ -84,6 +86,7 @@ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Operating System :: OS Independent", "Topic :: Internet", ], diff --git a/testing/constraints-3.14.txt b/testing/constraints-3.14.txt new file mode 100644 index 00000000..e69de29b From f86c964200cc16488e46fdd95ad78e7975760b53 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 13:50:58 -0500 Subject: [PATCH 02/11] fix: Deprecate credentials_file argument (#572) - [ ] Regenerate this pull request now. BEGIN_COMMIT_OVERRIDE fix: Deprecate credentials_file argument END_COMMIT_OVERRIDE fix: Deprecate credentials_file argument chore: Update gapic-generator-python to 1.28.0 PiperOrigin-RevId: 816753840 Source-Link: https://github.com/googleapis/googleapis/commit/d06cf27a47074d1de3fde6f0ca48680a96229306 Source-Link: https://github.com/googleapis/googleapis-gen/commit/a524e7310882bbb99bfe1399b18bed328979211c Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiYTUyNGU3MzEwODgyYmJiOTliZmUxMzk5YjE4YmVkMzI4OTc5MjExYyJ9 BEGIN_NESTED_COMMIT feat: Add new `BACKGROUND_CHANGE_DATA_CAPTURE`, `BACKGROUND_COLUMN_METADATA_INDEX`, and `BACKGROUND_SEARCH_INDEX_REFRESH` reservation assignment types feat: Add support for creation and modification of new reservation groups feat: Add new reservation IAM policy get/set/test methods PiperOrigin-RevId: 814816863 Source-Link: https://github.com/googleapis/googleapis/commit/2193a2bfcecb92b92aad7a4d81baa428cafd7dfd Source-Link: https://github.com/googleapis/googleapis-gen/commit/b0cf5f4c4051c9ddd7990be93ae8d008789d7286 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiYjBjZjVmNGM0MDUxYzlkZGQ3OTkwYmU5M2FlOGQwMDg3ODlkNzI4NiJ9 END_NESTED_COMMIT BEGIN_NESTED_COMMIT chore: Update gapic-generator-python to 1.26.2 PiperOrigin-RevId: 802200836 Source-Link: https://github.com/googleapis/googleapis/commit/d300b151a973ce0425ae4ad07b3de957ca31bec6 Source-Link: https://github.com/googleapis/googleapis-gen/commit/a1ff0ae72ddcb68a259215d8c77661e2cdbb9b02 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiYTFmZjBhZTcyZGRjYjY4YTI1OTIxNWQ4Yzc3NjYxZTJjZGJiOWIwMiJ9 END_NESTED_COMMIT BEGIN_NESTED_COMMIT chore: update Python generator version to 1.25.1 PiperOrigin-RevId: 800535761 Source-Link: https://github.com/googleapis/googleapis/commit/4cf1f99cccc014627af5e8a6c0f80a3e6ec0d268 Source-Link: https://github.com/googleapis/googleapis-gen/commit/133d25b68e712116e1c5dc71fc3eb3c5e717022a Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiMTMzZDI1YjY4ZTcxMjExNmUxYzVkYzcxZmMzZWIzYzVlNzE3MDIyYSJ9 END_NESTED_COMMIT --------- Co-authored-by: Owl Bot Co-authored-by: Anthonios Partheniou --- .../error_group_service/transports/base.py | 5 +-- .../error_group_service/transports/grpc.py | 8 +++-- .../transports/grpc_asyncio.py | 8 +++-- .../error_group_service/transports/rest.py | 5 +-- .../error_stats_service/transports/base.py | 5 +-- .../error_stats_service/transports/grpc.py | 8 +++-- .../transports/grpc_asyncio.py | 8 +++-- .../error_stats_service/transports/rest.py | 5 +-- .../report_errors_service/async_client.py | 16 ++++----- .../services/report_errors_service/client.py | 16 ++++----- .../report_errors_service/transports/base.py | 5 +-- .../report_errors_service/transports/grpc.py | 22 ++++++------ .../transports/grpc_asyncio.py | 22 ++++++------ .../report_errors_service/transports/rest.py | 5 +-- .../types/report_errors_service.py | 34 +++++++++---------- ....devtools.clouderrorreporting.v1beta1.json | 2 +- testing/constraints-3.10.txt | 2 ++ testing/constraints-3.11.txt | 2 ++ testing/constraints-3.12.txt | 2 ++ testing/constraints-3.13.txt | 1 + testing/constraints-3.14.txt | 12 +++++++ testing/constraints-3.9.txt | 2 ++ 22 files changed, 117 insertions(+), 78 deletions(-) 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 9938eaf4..e079b904 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 @@ -68,9 +68,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. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. scopes (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. 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 8bfab8f0..c208fdef 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 @@ -152,9 +152,10 @@ def __init__( are specified, the client will attempt to ascertain the credentials from the environment. This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. scopes (Optional(Sequence[str])): A list of scopes. This argument is ignored if a ``channel`` instance is provided. channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): @@ -287,9 +288,10 @@ def create_channel( credentials identify this application to the service. If none are specified, the client will attempt to ascertain the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. scopes (Optional[Sequence[str]]): A optional list of scopes needed for this service. These are only used when credentials are not specified and are passed to :func:`google.auth.default`. 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 f3186e61..bc8d9be0 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 @@ -149,8 +149,9 @@ def create_channel( credentials identify this application to the service. If none are specified, the client will attempt to ascertain the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. scopes (Optional[Sequence[str]]): A optional list of scopes needed for this service. These are only used when credentials are not specified and are passed to :func:`google.auth.default`. @@ -201,9 +202,10 @@ def __init__( are specified, the client will attempt to ascertain the credentials from the environment. This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. scopes (Optional[Sequence[str]]): A optional list of scopes needed for this service. These are only used when credentials are not specified and are passed to :func:`google.auth.default`. diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/rest.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/rest.py index 526f1d7f..ecbebae3 100644 --- a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/rest.py +++ b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/rest.py @@ -239,9 +239,10 @@ def __init__( are specified, the client will attempt to ascertain the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. + This argument is ignored if ``channel`` is provided. This argument will be + removed in the next major version of this library. scopes (Optional(Sequence[str])): A list of scopes. This argument is ignored if ``channel`` is provided. client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client 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 12f6992a..7cc2de51 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 @@ -67,9 +67,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. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. scopes (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. 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 9bcb9106..244aba2d 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 @@ -152,9 +152,10 @@ def __init__( are specified, the client will attempt to ascertain the credentials from the environment. This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. scopes (Optional(Sequence[str])): A list of scopes. This argument is ignored if a ``channel`` instance is provided. channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): @@ -287,9 +288,10 @@ def create_channel( credentials identify this application to the service. If none are specified, the client will attempt to ascertain the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. scopes (Optional[Sequence[str]]): A optional list of scopes needed for this service. These are only used when credentials are not specified and are passed to :func:`google.auth.default`. 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 a6211645..892bf1e0 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 @@ -149,8 +149,9 @@ def create_channel( credentials identify this application to the service. If none are specified, the client will attempt to ascertain the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. scopes (Optional[Sequence[str]]): A optional list of scopes needed for this service. These are only used when credentials are not specified and are passed to :func:`google.auth.default`. @@ -201,9 +202,10 @@ def __init__( are specified, the client will attempt to ascertain the credentials from the environment. This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. scopes (Optional[Sequence[str]]): A optional list of scopes needed for this service. These are only used when credentials are not specified and are passed to :func:`google.auth.default`. diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/rest.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/rest.py index 1b7a4cc5..52bde4cd 100644 --- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/rest.py +++ b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/rest.py @@ -308,9 +308,10 @@ def __init__( are specified, the client will attempt to ascertain the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. + This argument is ignored if ``channel`` is provided. This argument will be + removed in the next major version of this library. scopes (Optional(Sequence[str])): A list of scopes. This argument is ignored if ``channel`` is provided. client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client 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 33c90024..f07f8629 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 @@ -314,14 +314,14 @@ async def report_error_event( Cloud Logging and can analyze log entries when all of the following are true: - - Customer-managed encryption keys (CMEK) are disabled on the - log bucket. - - The log bucket satisfies one of the following: - - - The log bucket is stored in the same project where the - logs originated. - - The logs were routed to a project, and then that project - stored those logs in a log bucket that it owns. + - Customer-managed encryption keys (CMEK) are disabled on the + log bucket. + - The log bucket satisfies one of the following: + + - The log bucket is stored in the same project where the logs + originated. + - The logs were routed to a project, and then that project + stored those logs in a log bucket that it owns. .. code-block:: python 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 9dc31d29..357b85b6 100644 --- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py +++ b/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py @@ -717,14 +717,14 @@ def report_error_event( Cloud Logging and can analyze log entries when all of the following are true: - - Customer-managed encryption keys (CMEK) are disabled on the - log bucket. - - The log bucket satisfies one of the following: - - - The log bucket is stored in the same project where the - logs originated. - - The logs were routed to a project, and then that project - stored those logs in a log bucket that it owns. + - Customer-managed encryption keys (CMEK) are disabled on the + log bucket. + - The log bucket satisfies one of the following: + + - The log bucket is stored in the same project where the logs + originated. + - The logs were routed to a project, and then that project + stored those logs in a log bucket that it owns. .. code-block:: python 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 31f69093..f9599b51 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 @@ -67,9 +67,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. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. scopes (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. 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 023d0f0f..2fe1f2d5 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 @@ -151,9 +151,10 @@ def __init__( are specified, the client will attempt to ascertain the credentials from the environment. This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. scopes (Optional(Sequence[str])): A list of scopes. This argument is ignored if a ``channel`` instance is provided. channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): @@ -286,9 +287,10 @@ def create_channel( credentials identify this application to the service. If none are specified, the client will attempt to ascertain the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. scopes (Optional[Sequence[str]]): A optional list of scopes needed for this service. These are only used when credentials are not specified and are passed to :func:`google.auth.default`. @@ -343,14 +345,14 @@ def report_error_event( Cloud Logging and can analyze log entries when all of the following are true: - - Customer-managed encryption keys (CMEK) are disabled on the - log bucket. - - The log bucket satisfies one of the following: + - Customer-managed encryption keys (CMEK) are disabled on the + log bucket. + - The log bucket satisfies one of the following: - - The log bucket is stored in the same project where the - logs originated. - - The logs were routed to a project, and then that project - stored those logs in a log bucket that it owns. + - The log bucket is stored in the same project where the logs + originated. + - The logs were routed to a project, and then that project + stored those logs in a log bucket that it owns. 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 18f942ce..4f538187 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 @@ -148,8 +148,9 @@ def create_channel( credentials identify this application to the service. If none are specified, the client will attempt to ascertain the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. scopes (Optional[Sequence[str]]): A optional list of scopes needed for this service. These are only used when credentials are not specified and are passed to :func:`google.auth.default`. @@ -200,9 +201,10 @@ def __init__( are specified, the client will attempt to ascertain the credentials from the environment. This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. scopes (Optional[Sequence[str]]): A optional list of scopes needed for this service. These are only used when credentials are not specified and are passed to :func:`google.auth.default`. @@ -351,14 +353,14 @@ def report_error_event( Cloud Logging and can analyze log entries when all of the following are true: - - Customer-managed encryption keys (CMEK) are disabled on the - log bucket. - - The log bucket satisfies one of the following: + - Customer-managed encryption keys (CMEK) are disabled on the + log bucket. + - The log bucket satisfies one of the following: - - The log bucket is stored in the same project where the - logs originated. - - The logs were routed to a project, and then that project - stored those logs in a log bucket that it owns. + - The log bucket is stored in the same project where the logs + originated. + - The logs were routed to a project, and then that project + stored those logs in a log bucket that it owns. Returns: Callable[[~.ReportErrorEventRequest], diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/rest.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/rest.py index 98c63125..9cebe03c 100644 --- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/rest.py +++ b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/rest.py @@ -190,9 +190,10 @@ def __init__( are specified, the client will attempt to ascertain the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can + credentials_file (Optional[str]): Deprecated. A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. + This argument is ignored if ``channel`` is provided. This argument will be + removed in the next major version of this library. scopes (Optional(Sequence[str])): A list of scopes. This argument is ignored if ``channel`` is provided. client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client diff --git a/google/cloud/errorreporting_v1beta1/types/report_errors_service.py b/google/cloud/errorreporting_v1beta1/types/report_errors_service.py index ebd33856..2a5072fb 100644 --- a/google/cloud/errorreporting_v1beta1/types/report_errors_service.py +++ b/google/cloud/errorreporting_v1beta1/types/report_errors_service.py @@ -91,23 +91,23 @@ class ReportedErrorEvent(proto.Message): Supported languages are Java, Python, JavaScript, Ruby, C#, PHP, and Go. Supported stack trace formats are: - - **Java**: Must be the return value of - ```Throwable.printStackTrace()`` `__. - - **Python**: Must be the return value of - ```traceback.format_exc()`` `__. - - **JavaScript**: Must be the value of - ```error.stack`` `__ - as returned by V8. - - **Ruby**: Must contain frames returned by - ```Exception.backtrace`` `__. - - **C#**: Must be the return value of - ```Exception.ToString()`` `__. - - **PHP**: Must be prefixed with - ``"PHP (Notice|Parse error|Fatal error|Warning): "`` and - contain the result of - ```(string)$exception`` `__. - - **Go**: Must be the return value of - ```runtime.Stack()`` `__. + - **Java**: Must be the return value of + ```Throwable.printStackTrace()`` `__. + - **Python**: Must be the return value of + ```traceback.format_exc()`` `__. + - **JavaScript**: Must be the value of + ```error.stack`` `__ + as returned by V8. + - **Ruby**: Must contain frames returned by + ```Exception.backtrace`` `__. + - **C#**: Must be the return value of + ```Exception.ToString()`` `__. + - **PHP**: Must be prefixed with + ``"PHP (Notice|Parse error|Fatal error|Warning): "`` and + contain the result of + ```(string)$exception`` `__. + - **Go**: Must be the return value of + ```runtime.Stack()`` `__. context (google.cloud.errorreporting_v1beta1.types.ErrorContext): Optional. A description of the context in which the error occurred. diff --git a/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json b/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json index 226f3879..ac59d817 100644 --- a/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json +++ b/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-error-reporting", - "version": "1.12.0" + "version": "0.0.0" }, "snippets": [ { diff --git a/testing/constraints-3.10.txt b/testing/constraints-3.10.txt index ed7f9aed..93e6826f 100644 --- a/testing/constraints-3.10.txt +++ b/testing/constraints-3.10.txt @@ -2,5 +2,7 @@ # This constraints file is required for unit tests. # List all library dependencies and extras in this file. google-api-core +google-auth +grpcio proto-plus protobuf diff --git a/testing/constraints-3.11.txt b/testing/constraints-3.11.txt index ed7f9aed..93e6826f 100644 --- a/testing/constraints-3.11.txt +++ b/testing/constraints-3.11.txt @@ -2,5 +2,7 @@ # This constraints file is required for unit tests. # List all library dependencies and extras in this file. google-api-core +google-auth +grpcio proto-plus protobuf diff --git a/testing/constraints-3.12.txt b/testing/constraints-3.12.txt index ed7f9aed..93e6826f 100644 --- a/testing/constraints-3.12.txt +++ b/testing/constraints-3.12.txt @@ -2,5 +2,7 @@ # This constraints file is required for unit tests. # List all library dependencies and extras in this file. google-api-core +google-auth +grpcio proto-plus protobuf diff --git a/testing/constraints-3.13.txt b/testing/constraints-3.13.txt index c20a7781..1e93c60e 100644 --- a/testing/constraints-3.13.txt +++ b/testing/constraints-3.13.txt @@ -7,5 +7,6 @@ # Then this file should have google-cloud-foo>=1 google-api-core>=2 google-auth>=2 +grpcio>=1 proto-plus>=1 protobuf>=6 diff --git a/testing/constraints-3.14.txt b/testing/constraints-3.14.txt index e69de29b..1e93c60e 100644 --- a/testing/constraints-3.14.txt +++ b/testing/constraints-3.14.txt @@ -0,0 +1,12 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +google-api-core>=2 +google-auth>=2 +grpcio>=1 +proto-plus>=1 +protobuf>=6 diff --git a/testing/constraints-3.9.txt b/testing/constraints-3.9.txt index ed7f9aed..93e6826f 100644 --- a/testing/constraints-3.9.txt +++ b/testing/constraints-3.9.txt @@ -2,5 +2,7 @@ # This constraints file is required for unit tests. # List all library dependencies and extras in this file. google-api-core +google-auth +grpcio proto-plus protobuf From c325399ea6b6cc1a5b58794a40ae9088c9001d5d Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 13:55:53 -0500 Subject: [PATCH 03/11] chore(main): release 1.13.0 (#713) :robot: I have created a release *beep* *boop* --- ## [1.13.0](https://github.com/googleapis/python-error-reporting/compare/v1.12.0...v1.13.0) (2025-11-12) ### Features * Add support for Python 3.14 ([#712](https://github.com/googleapis/python-error-reporting/issues/712)) ([e8b4762](https://github.com/googleapis/python-error-reporting/commit/e8b4762d289755377acb7c69744a347fbe6651d6)) ### Bug Fixes * Deprecate credentials_file argument ([f86c964](https://github.com/googleapis/python-error-reporting/commit/f86c964200cc16488e46fdd95ad78e7975760b53)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 12 ++++++++++++ google/cloud/error_reporting/gapic_version.py | 2 +- google/cloud/errorreporting_v1beta1/gapic_version.py | 2 +- ..._google.devtools.clouderrorreporting.v1beta1.json | 2 +- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b3960c05..5c63354e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.12.0" + ".": "1.13.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index a09f8129..9f9a8318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,18 @@ [1]: https://pypi.org/project/google-cloud-error-reporting/#history +## [1.13.0](https://github.com/googleapis/python-error-reporting/compare/v1.12.0...v1.13.0) (2025-11-12) + + +### Features + +* Add support for Python 3.14 ([#712](https://github.com/googleapis/python-error-reporting/issues/712)) ([e8b4762](https://github.com/googleapis/python-error-reporting/commit/e8b4762d289755377acb7c69744a347fbe6651d6)) + + +### Bug Fixes + +* Deprecate credentials_file argument ([f86c964](https://github.com/googleapis/python-error-reporting/commit/f86c964200cc16488e46fdd95ad78e7975760b53)) + ## [1.12.0](https://github.com/googleapis/python-error-reporting/compare/v1.11.1...v1.12.0) (2025-05-21) diff --git a/google/cloud/error_reporting/gapic_version.py b/google/cloud/error_reporting/gapic_version.py index 7138f214..1fc1b24b 100644 --- a/google/cloud/error_reporting/gapic_version.py +++ b/google/cloud/error_reporting/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.12.0" # {x-release-please-version} +__version__ = "1.13.0" # {x-release-please-version} diff --git a/google/cloud/errorreporting_v1beta1/gapic_version.py b/google/cloud/errorreporting_v1beta1/gapic_version.py index 7138f214..1fc1b24b 100644 --- a/google/cloud/errorreporting_v1beta1/gapic_version.py +++ b/google/cloud/errorreporting_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.12.0" # {x-release-please-version} +__version__ = "1.13.0" # {x-release-please-version} diff --git a/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json b/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json index ac59d817..1d772531 100644 --- a/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json +++ b/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-error-reporting", - "version": "0.0.0" + "version": "1.13.0" }, "snippets": [ { From 724cc7d4b0ce9f44133d92c4c2d28fbd09f8ae43 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Wed, 12 Nov 2025 16:01:05 -0500 Subject: [PATCH 04/11] chore(librarian): onboard to librarian (#715) Towards https://github.com/googleapis/librarian/issues/2459 --- .flake8 | 15 +- .github/.OwlBot.lock.yaml | 16 - .github/.OwlBot.yaml | 26 - .github/auto-approve.yml | 3 - .github/release-please.yml | 9 - .../generator-input/.repo-metadata.json | 18 + .librarian/generator-input/noxfile.py | 487 ++++++++++++++++++ .librarian/generator-input/owlbot.py | 76 +++ .librarian/generator-input/setup.py | 99 ++++ .librarian/state.yaml | 42 ++ .release-please-manifest.json | 3 - MANIFEST.in | 13 +- docs/README.rst | 198 ++++++- docs/_templates/layout.html | 4 +- .../errorreporting_v1beta1/gapic_version.py | 2 +- owlbot.py | 25 +- release-please-config.json | 24 - 17 files changed, 938 insertions(+), 122 deletions(-) delete mode 100644 .github/.OwlBot.lock.yaml delete mode 100644 .github/.OwlBot.yaml delete mode 100644 .github/auto-approve.yml delete mode 100644 .github/release-please.yml create mode 100644 .librarian/generator-input/.repo-metadata.json create mode 100644 .librarian/generator-input/noxfile.py create mode 100644 .librarian/generator-input/owlbot.py create mode 100644 .librarian/generator-input/setup.py create mode 100644 .librarian/state.yaml delete mode 100644 .release-please-manifest.json mode change 120000 => 100644 docs/README.rst delete mode 100644 release-please-config.json diff --git a/.flake8 b/.flake8 index 32986c79..90316de2 100644 --- a/.flake8 +++ b/.flake8 @@ -1,28 +1,29 @@ # -*- coding: utf-8 -*- -# -# Copyright 2024 Google LLC +# Copyright 2025 Google LLC # # Licensed under the Apache License, Version 2.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 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - -# Generated by synthtool. DO NOT EDIT! +# [flake8] +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): +# Resolve flake8 lint issues ignore = E203, E231, E266, E501, W503 exclude = - # Exclude generated code. - **/proto/** + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): + # Ensure that generated code passes flake8 lint **/gapic/** **/services/** **/types/** + # Exclude Protobuf gencode *_pb2.py # Standard linting exemptions. diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml deleted file mode 100644 index c58733d0..00000000 --- a/.github/.OwlBot.lock.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -docker: - image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - digest: sha256:fbbc8db67afd8b7d71bf694c5081a32da0c528eba166fbcffb3b6e56ddf907d5 diff --git a/.github/.OwlBot.yaml b/.github/.OwlBot.yaml deleted file mode 100644 index 18f04683..00000000 --- a/.github/.OwlBot.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2021 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -docker: - image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - -deep-remove-regex: - - /owl-bot-staging - -deep-copy-regex: - - source: /google/devtools/clouderrorreporting/(v.*)/.*-py/(.*) - dest: /owl-bot-staging/$1/$2 - -begin-after-commit-hash: b06c9034cfcbce180ba732d03be6526e5c8ea1bc - diff --git a/.github/auto-approve.yml b/.github/auto-approve.yml deleted file mode 100644 index 311ebbb8..00000000 --- a/.github/auto-approve.yml +++ /dev/null @@ -1,3 +0,0 @@ -# https://github.com/googleapis/repo-automation-bots/tree/main/packages/auto-approve -processes: - - "OwlBotTemplateChanges" diff --git a/.github/release-please.yml b/.github/release-please.yml deleted file mode 100644 index e9a4f008..00000000 --- a/.github/release-please.yml +++ /dev/null @@ -1,9 +0,0 @@ -releaseType: python -handleGHRelease: true -manifest: true -# NOTE: this section is generated by synthtool.languages.python -# See https://github.com/googleapis/synthtool/blob/master/synthtool/languages/python.py -branches: -- branch: v0 - handleGHRelease: true - releaseType: python diff --git a/.librarian/generator-input/.repo-metadata.json b/.librarian/generator-input/.repo-metadata.json new file mode 100644 index 00000000..e032093f --- /dev/null +++ b/.librarian/generator-input/.repo-metadata.json @@ -0,0 +1,18 @@ +{ + "name": "clouderrorreporting", + "name_pretty": "Error Reporting", + "product_documentation": "https://cloud.google.com/error-reporting", + "client_documentation": "https://cloud.google.com/python/docs/reference/clouderrorreporting/latest", + "issue_tracker": "https://issuetracker.google.com/savedsearches/559780", + "release_level": "preview", + "language": "python", + "library_type": "GAPIC_COMBO", + "repo": "googleapis/python-error-reporting", + "distribution_name": "google-cloud-error-reporting", + "api_id": "clouderrorreporting.googleapis.com", + "requires_billing": false, + "codeowner_team": "@googleapis/api-logging @googleapis/api-logging-partners", + "default_version": "v1beta1", + "api_shortname": "clouderrorreporting", + "api_description": "counts, analyzes and aggregates the crashes in your running cloud services. A centralized error management interface displays the results with sorting and filtering capabilities. A dedicated view shows the error details: time chart, occurrences, affected user count, first and last seen dates and a cleaned exception stack trace. Opt-in to receive email and mobile alerts on new errors." +} diff --git a/.librarian/generator-input/noxfile.py b/.librarian/generator-input/noxfile.py new file mode 100644 index 00000000..35c5330b --- /dev/null +++ b/.librarian/generator-input/noxfile.py @@ -0,0 +1,487 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.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! + +from __future__ import absolute_import + +import os +import pathlib +import re +import shutil +from typing import Dict, List +import warnings + +import nox + +FLAKE8_VERSION = "flake8==6.1.0" +BLACK_VERSION = "black[jupyter]==23.7.0" +ISORT_VERSION = "isort==5.11.0" +LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] + +DEFAULT_PYTHON_VERSION = "3.14" + +UNIT_TEST_PYTHON_VERSIONS: List[str] = [ + "3.7", + "3.8", + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", + "3.14", +] +UNIT_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "asyncmock", + "pytest", + "pytest-cov", + "pytest-asyncio", +] +UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_DEPENDENCIES: List[str] = [] +UNIT_TEST_EXTRAS: List[str] = [] +UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.14"] +SYSTEM_TEST_STANDARD_DEPENDENCIES: List[str] = [ + "mock", + "pytest", + "google-cloud-testutils", +] +SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_EXTRAS: List[str] = [] +SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +nox.options.sessions = [ + "system", +] + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint(session): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install(FLAKE8_VERSION, BLACK_VERSION) + session.run( + "black", + "--check", + *LINT_PATHS, + ) + session.run("flake8", "google", "tests") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + session.run( + "black", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run( + "isort", + "--fss", + *LINT_PATHS, + ) + session.run( + "black", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("docutils", "pygments", "setuptools") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") + + +def install_unittest_dependencies(session, *constraints): + standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES + session.install(*standard_deps, *constraints) + + if UNIT_TEST_EXTERNAL_DEPENDENCIES: + warnings.warn( + "'unit_test_external_dependencies' is deprecated. Instead, please " + "use 'unit_test_dependencies' or 'unit_test_local_dependencies'.", + DeprecationWarning, + ) + session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_LOCAL_DEPENDENCIES: + session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_EXTRAS_BY_PYTHON: + extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif UNIT_TEST_EXTRAS: + extras = UNIT_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@nox.session(python=UNIT_TEST_PYTHON_VERSIONS) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb", "cpp"], +) +def unit(session, protobuf_implementation): + # Install all test dependencies, then install this package in-place. + + if protobuf_implementation == "cpp" and session.python in ( + "3.11", + "3.12", + "3.13", + "3.14", + ): + session.skip("cpp implementation is not supported in python 3.11+") + + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + install_unittest_dependencies(session, "-c", constraints_path) + + # TODO(https://github.com/googleapis/synthtool/issues/1976): + # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. + # The 'cpp' implementation requires Protobuf<4. + if protobuf_implementation == "cpp": + session.install("protobuf<4") + + # Run py.test against the unit tests. + session.run( + "py.test", + "--quiet", + f"--junitxml=unit_{session.python}_sponge_log.xml", + "--cov=google", + "--cov=tests/unit", + "--cov-append", + "--cov-config=.coveragerc", + "--cov-report=", + "--cov-fail-under=0", + os.path.join("tests", "unit"), + *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +def install_systemtest_dependencies(session, *constraints): + # Use pre-release gRPC for system tests. + # Exclude version 1.52.0rc1 which has a known issue. + # See https://github.com/grpc/grpc/issues/32163 + session.install("--pre", "grpcio!=1.52.0rc1") + + session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTERNAL_DEPENDENCIES: + session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_LOCAL_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTRAS_BY_PYTHON: + extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif SYSTEM_TEST_EXTRAS: + extras = SYSTEM_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) +def system(session): + """Run the system test suite.""" + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + system_test_path = os.path.join("tests", "system.py") + system_test_folder_path = os.path.join("tests", "system") + + # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. + if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": + session.skip("RUN_SYSTEM_TESTS is set to false, skipping") + # 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) + # Sanity check: only run tests if found. + if not system_test_exists and not system_test_folder_exists: + session.skip("System tests were not found") + + install_systemtest_dependencies(session, "-c", constraints_path) + + # Run py.test against the system tests. + if system_test_exists: + 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", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def cover(session): + """Run the final coverage report. + + This outputs the coverage report aggregating coverage from the unit + test runs (not system test runs), and then erases coverage data. + """ + session.install("coverage", "pytest-cov") + session.run("coverage", "report", "--show-missing", "--fail-under=100") + + session.run("coverage", "erase") + + +@nox.session(python="3.10") +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "sphinx==4.5.0", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-W", # warnings as errors + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python="3.10") +def docfx(session): + """Build the docfx yaml files for this library.""" + + session.install("-e", ".") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "gcp-sphinx-docfx-yaml", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-D", + ( + "extensions=sphinx.ext.autodoc," + "sphinx.ext.autosummary," + "docfx_yaml.extension," + "sphinx.ext.intersphinx," + "sphinx.ext.coverage," + "sphinx.ext.napoleon," + "sphinx.ext.todo," + "sphinx.ext.viewcode," + "recommonmark" + ), + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb", "cpp"], +) +def prerelease_deps(session, protobuf_implementation): + """Run all tests with prerelease versions of dependencies installed.""" + + if protobuf_implementation == "cpp" and session.python in ( + "3.11", + "3.12", + "3.13", + "3.14", + ): + session.skip("cpp implementation is not supported in python 3.11+") + + # Install all dependencies + session.install("-e", ".[all, tests, tracing]") + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + system_deps_all = ( + SYSTEM_TEST_STANDARD_DEPENDENCIES + SYSTEM_TEST_EXTERNAL_DEPENDENCIES + ) + session.install(*system_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY + / "testing" + / f"constraints-{UNIT_TEST_PYTHON_VERSIONS[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + session.install(*constraints_deps) + + prerel_deps = [ + "protobuf", + # dependency of grpc + "six", + "grpc-google-iam-v1", + "googleapis-common-protos", + "grpcio", + "grpcio-status", + "google-api-core", + "google-auth", + "proto-plus", + "google-cloud-testutils", + # dependencies of google-cloud-testutils" + "click", + ] + + for dep in prerel_deps: + session.install("--pre", "--no-deps", "--upgrade", dep) + + # Remaining dependencies + other_deps = [ + "requests", + ] + session.install(*other_deps) + + # Print out prerelease package versions + session.run( + "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" + ) + session.run("python", "-c", "import grpc; print(grpc.__version__)") + session.run("python", "-c", "import google.auth; print(google.auth.__version__)") + + session.run( + "py.test", + "tests/unit", + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + system_test_path = os.path.join("tests", "system.py") + system_test_folder_path = os.path.join("tests", "system") + + # Only run system tests if found. + if os.path.exists(system_test_path): + session.run( + "py.test", + "--verbose", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_path, + *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + if os.path.exists(system_test_folder_path): + session.run( + "py.test", + "--verbose", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) diff --git a/.librarian/generator-input/owlbot.py b/.librarian/generator-input/owlbot.py new file mode 100644 index 00000000..76977beb --- /dev/null +++ b/.librarian/generator-input/owlbot.py @@ -0,0 +1,76 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +from pathlib import Path +import shutil + +import synthtool as s +import synthtool.gcp as gcp +from synthtool.languages import python + +# ---------------------------------------------------------------------------- +# Copy the generated client from the owl-bot staging directory +# ---------------------------------------------------------------------------- + +clean_up_generated_samples = True + +# Load the default version defined in .repo-metadata.json. +default_version = json.load(open(".repo-metadata.json", "rt")).get("default_version") + +for library in s.get_staging_dirs(default_version): + if clean_up_generated_samples: + shutil.rmtree("samples/generated_samples", ignore_errors=True) + clean_up_generated_samples = False + + s.move( + [library], + excludes=[ + "docs/index.rst", + "google/cloud/errorreporting/", + "setup.py", + "testing/constraints-3.7.txt", + "testing/constraints-3.8.txt", + "noxfile.py", + ], + ) +s.remove_staging_dirs() + +# ---------------------------------------------------------------------------- +# Add templated files +# ---------------------------------------------------------------------------- + +templated_files = gcp.CommonTemplates().py_library( + cov_level=100, + microgenerator=True, + versions=gcp.common.detect_versions(path="./google", default_first=True), +) +s.move( + templated_files, + excludes=[ + ".coveragerc", + ".github/**", + ".kokoro/**", + "docs/conf.py", + "docs/index.rst", + "testing/constraints-3.7.txt", + ], +) + +python.py_samples(skip_readmes=True) + +# run format session for all directories which have a noxfile +for noxfile in Path(".").glob("**/noxfile.py"): + s.shell.run(["nox", "-s", "blacken"], cwd=noxfile.parent, hide_output=False) diff --git a/.librarian/generator-input/setup.py b/.librarian/generator-input/setup.py new file mode 100644 index 00000000..c80d2b25 --- /dev/null +++ b/.librarian/generator-input/setup.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import io +import os + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = "google-cloud-error-reporting" + + +description = "Google Cloud Error Reporting API client library" + +version = {} +with open( + os.path.join(package_root, "google/cloud/error_reporting/gapic_version.py") +) as fp: + exec(fp.read(), version) +version = version["__version__"] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-cloud-logging>=1.14.0, <4.0.0", + # Exclude incompatible versions of `google-auth` + # See https://github.com/googleapis/google-cloud-python/issues/12364 + "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", + "google-api-core[grpc] >= 1.34.0, <3.0.0,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", + "grpcio >= 1.33.2, < 2.0.0", + "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "proto-plus >= 1.22.0, <2.0.0", + "proto-plus >= 1.22.2, <2.0.0; python_version>='3.11'", + "proto-plus >= 1.25.0, <2.0.0dev; python_version>='3.13'", + "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", +] +url = "https://github.com/googleapis/python-error-reporting" + +package_root = os.path.abspath(os.path.dirname(__file__)) + +readme_filename = os.path.join(package_root, "README.rst") +with io.open(readme_filename, encoding="utf-8") as readme_file: + readme = readme_file.read() + +packages = [ + package + for package in setuptools.find_namespace_packages() + if package.startswith("google") +] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache 2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + python_requires=">=3.7", + install_requires=dependencies, + include_package_data=True, + zip_safe=False, +) diff --git a/.librarian/state.yaml b/.librarian/state.yaml new file mode 100644 index 00000000..b4a06d7e --- /dev/null +++ b/.librarian/state.yaml @@ -0,0 +1,42 @@ +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:ce48ed695c727f7e13efd1fd68f466a55a0d772c87b69158720cec39965bc8b2 +libraries: + - id: google-cloud-error-reporting + version: 1.13.0 + last_generated_commit: cf0434f4bd20618db60ddd16a1e7db2c0dfb9158 + apis: + - path: google/devtools/clouderrorreporting/v1beta1 + service_config: clouderrorreporting_v1beta1.yaml + source_roots: + - . + preserve_regex: [] + remove_regex: + - ^google/cloud/errorreporting_v1beta1 + - ^docs/_static + - ^docs/_templates + - ^docs/errorreporting_v1beta1 + - ^docs/multiprocessing.rst + - ^docs/conf.py + - ^docs/README.rst + - ^docs/summary_overview.md + - ^tests/unit/gapic + - ^tests/__init__.py + - ^tests/unit/__init__.py + - ^.coveragerc + - ^.flake8 + - ^.pre-commit-config.yaml + - ^.repo-metadata.json + - ^.trampolinerc + - ^LICENSE + - ^MANIFEST.in + - ^README.rst + - ^SECURITY.md + - ^mypy.ini + - ^noxfile.py + - ^owlbot.py + - ^renovate.json + - ^samples/generated_samples + - ^scripts/fixup_ + - ^setup.py + - ^testing/constraints-3.9 + - ^testing/constraints-3.1 + tag_format: v{version} diff --git a/.release-please-manifest.json b/.release-please-manifest.json deleted file mode 100644 index 5c63354e..00000000 --- a/.release-please-manifest.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - ".": "1.13.0" -} diff --git a/MANIFEST.in b/MANIFEST.in index d6814cd6..dae249ec 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,25 +1,20 @@ # -*- coding: utf-8 -*- -# -# Copyright 2024 Google LLC +# Copyright 2025 Google LLC # # Licensed under the Apache License, Version 2.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 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES 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! +# include README.rst LICENSE -recursive-include google *.json *.proto py.typed +recursive-include google *.py *.pyi *.json *.proto py.typed recursive-include tests * global-exclude *.py[co] global-exclude __pycache__ - -# Exclude scripts for samples readmegen -prune scripts/readme-gen diff --git a/docs/README.rst b/docs/README.rst deleted file mode 120000 index 89a01069..00000000 --- a/docs/README.rst +++ /dev/null @@ -1 +0,0 @@ -../README.rst \ No newline at end of file diff --git a/docs/README.rst b/docs/README.rst new file mode 100644 index 00000000..7a401641 --- /dev/null +++ b/docs/README.rst @@ -0,0 +1,197 @@ +Python Client for Error Reporting API +===================================== + +|preview| |pypi| |versions| + +`Error Reporting API`_: counts, analyzes and aggregates the crashes in your running cloud services. A centralized error management interface displays the results with sorting and filtering capabilities. A dedicated view shows the error details: time chart, occurrences, affected user count, first and last seen dates and a cleaned exception stack trace. Opt-in to receive email and mobile alerts on new errors. + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/google-cloud-error-reporting.svg + :target: https://pypi.org/project/google-cloud-error-reporting/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-cloud-error-reporting.svg + :target: https://pypi.org/project/google-cloud-error-reporting/ +.. _Error Reporting API: https://cloud.google.com/error-reporting +.. _Client Library Documentation: https://cloud.google.com/python/docs/reference/clouderrorreporting/latest/summary_overview +.. _Product Documentation: https://cloud.google.com/error-reporting + +Quick Start +----------- + +In order to use this library, you first need to go through the following steps: + +1. `Select or create a Cloud Platform project.`_ +2. `Enable billing for your project.`_ +3. `Enable the Error Reporting API.`_ +4. `Set up Authentication.`_ + +.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project +.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project +.. _Enable the Error Reporting API.: https://cloud.google.com/error-reporting +.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/python-error-reporting/tree/main/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.7, including 3.14 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.6 + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install google-cloud-error-reporting + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install google-cloud-error-reporting + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for Error Reporting API + to see other available methods on the client. +- Read the `Error Reporting API Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _Error Reporting API Product documentation: https://cloud.google.com/error-reporting +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst + +Logging +------- + +This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. +Note the following: + +#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. +#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. +#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. + +Simple, environment-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google +logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged +messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging +event. + +A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. + +- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. +- Invalid logging scopes: :code:`foo`, :code:`123`, etc. + +**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. + +Environment-Based Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Enabling the default handler for all Google-based loggers + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google + +- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 + + +Advanced, code-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also configure a valid logging scope using Python's standard `logging` mechanism. + +Code-Based Examples +^^^^^^^^^^^^^^^^^^^ + +- Configuring a handler for all Google-based loggers + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google.cloud.library_v1") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +Logging details +~~~~~~~~~~~~~~~ + +#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root + logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set + :code:`logging.getLogger("google").propagate = True` in your code. +#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for + one library, but decide you need to also set up environment-based logging configuration for another library. + + #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual + if the code -based configuration gets applied first. + +#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get + executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. + (This is the reason for 2.i. above.) diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html index 6316a537..95e9c77f 100644 --- a/docs/_templates/layout.html +++ b/docs/_templates/layout.html @@ -20,8 +20,8 @@ {% endblock %}
-
- As of January 1, 2020 this library no longer supports Python 2 on the latest released version. +
+ As of January 1, 2020 this library no longer supports Python 2 on the latest released version. Library versions released prior to that date will continue to be available. For more information please visit Python 2 support on Google Cloud.
diff --git a/google/cloud/errorreporting_v1beta1/gapic_version.py b/google/cloud/errorreporting_v1beta1/gapic_version.py index 1fc1b24b..4cccf771 100644 --- a/google/cloud/errorreporting_v1beta1/gapic_version.py +++ b/google/cloud/errorreporting_v1beta1/gapic_version.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2022 Google LLC +# Copyright 2025 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/owlbot.py b/owlbot.py index c45fc6bf..76977beb 100644 --- a/owlbot.py +++ b/owlbot.py @@ -38,12 +38,12 @@ s.move( [library], excludes=[ - "**/gapic_version.py", "docs/index.rst", "google/cloud/errorreporting/", "setup.py", "testing/constraints-3.7.txt", "testing/constraints-3.8.txt", + "noxfile.py", ], ) s.remove_staging_dirs() @@ -56,14 +56,14 @@ cov_level=100, microgenerator=True, versions=gcp.common.detect_versions(path="./google", default_first=True), - default_python_version="3.14" ) s.move( templated_files, excludes=[ ".coveragerc", - ".github/release-please.yml", - ".github/auto-label.yaml", + ".github/**", + ".kokoro/**", + "docs/conf.py", "docs/index.rst", "testing/constraints-3.7.txt", ], @@ -74,20 +74,3 @@ # run format session for all directories which have a noxfile for noxfile in Path(".").glob("**/noxfile.py"): s.shell.run(["nox", "-s", "blacken"], cwd=noxfile.parent, hide_output=False) - -# -------------------------------------------------------------------------- -# Modify test configs -# -------------------------------------------------------------------------- - -# add shared environment variables to test configs -tracked_subdirs = ["continuous", "presubmit", "samples"] -for subdir in tracked_subdirs: - for path, subdirs, files in os.walk(f".kokoro/{subdir}"): - for name in files: - if name == "common.cfg": - file_path = os.path.join(path, name) - s.move( - ".kokoro/common_env_vars.cfg", - file_path, - merge=lambda src, dst, _,: f"{dst}\n{src}", - ) diff --git a/release-please-config.json b/release-please-config.json deleted file mode 100644 index 27b697b9..00000000 --- a/release-please-config.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", - "packages": { - ".": { - "release-type": "python", - "extra-files": [ - "google/cloud/error_reporting/gapic_version.py", - "google/cloud/errorreporting_v1beta1/gapic_version.py", - { - "type": "json", - "path": "samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json", - "jsonpath": "$.clientLibrary.version" - } - ] - } - }, - "release-type": "python", - "plugins": [ - { - "type": "sentence-case" - } - ], - "initial-version": "0.1.0" -} From 7e99258b41ddef55b63c70c7e31afced4ab30103 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Tue, 16 Dec 2025 15:10:45 -0500 Subject: [PATCH 05/11] feat(gapic): support mTLS certificates when available (#717) chore: librarian update image pull request: 20251216T195732Z --- .../{owlbot.py => librarian.py} | 0 .librarian/state.yaml | 2 +- docs/conf.py | 19 +- .../cloud/errorreporting_v1beta1/__init__.py | 104 +++++++ .../services/error_group_service/client.py | 46 +++- .../services/error_stats_service/client.py | 46 +++- .../services/report_errors_service/client.py | 46 +++- owlbot.py => librarian.py | 0 noxfile.py | 4 + pytest.ini | 2 + .../fixup_errorreporting_v1beta1_keywords.py | 181 ------------- setup.py | 4 + .../test_error_group_service.py | 255 ++++++++++++++++-- .../test_error_stats_service.py | 255 ++++++++++++++++-- .../test_report_errors_service.py | 255 ++++++++++++++++-- 15 files changed, 899 insertions(+), 320 deletions(-) rename .librarian/generator-input/{owlbot.py => librarian.py} (100%) rename owlbot.py => librarian.py (100%) delete mode 100644 scripts/fixup_errorreporting_v1beta1_keywords.py diff --git a/.librarian/generator-input/owlbot.py b/.librarian/generator-input/librarian.py similarity index 100% rename from .librarian/generator-input/owlbot.py rename to .librarian/generator-input/librarian.py diff --git a/.librarian/state.yaml b/.librarian/state.yaml index b4a06d7e..c12cabcf 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,4 +1,4 @@ -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:ce48ed695c727f7e13efd1fd68f466a55a0d772c87b69158720cec39965bc8b2 +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209 libraries: - id: google-cloud-error-reporting version: 1.13.0 diff --git a/docs/conf.py b/docs/conf.py index fd79abb7..6a191f48 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- -# Copyright 2024 Google LLC +# Copyright 2025 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# # google-cloud-error-reporting documentation build configuration file # # This file is execfile()d with the current directory set to its @@ -42,7 +43,7 @@ # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = "1.5.5" +needs_sphinx = "4.5.0" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom @@ -81,7 +82,7 @@ # General information about the project. project = "google-cloud-error-reporting" -copyright = "2019, Google" +copyright = "2025, Google, LLC" author = "Google APIs" # The version info for the project you're documenting, acts as replacement for @@ -156,7 +157,7 @@ html_theme_options = { "description": "Google Cloud Client Libraries for google-cloud-error-reporting", "github_user": "googleapis", - "github_repo": "python-error-reporting", + "github_repo": "google-cloud-python", "github_banner": True, "font_family": "'Roboto', Georgia, sans", "head_font_family": "'Roboto', Georgia, serif", @@ -266,13 +267,13 @@ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). - #'papersize': 'letterpaper', + # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). - #'pointsize': '10pt', + # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. - #'preamble': '', + # 'preamble': '', # Latex figure (float) alignment - #'figure_align': 'htbp', + # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples diff --git a/google/cloud/errorreporting_v1beta1/__init__.py b/google/cloud/errorreporting_v1beta1/__init__.py index e6ff221d..82b5b2ee 100644 --- a/google/cloud/errorreporting_v1beta1/__init__.py +++ b/google/cloud/errorreporting_v1beta1/__init__.py @@ -15,8 +15,18 @@ # from google.cloud.errorreporting_v1beta1 import gapic_version as package_version +import google.api_core as api_core +import sys + __version__ = package_version.__version__ +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata + from .services.error_group_service import ErrorGroupServiceClient from .services.error_group_service import ErrorGroupServiceAsyncClient @@ -51,6 +61,100 @@ from .types.report_errors_service import ReportErrorEventRequest from .types.report_errors_service import ReportErrorEventResponse +if hasattr(api_core, "check_python_version") and hasattr( + api_core, "check_dependency_versions" +): # pragma: NO COVER + api_core.check_python_version("google.cloud.errorreporting_v1beta1") # type: ignore + api_core.check_dependency_versions("google.cloud.errorreporting_v1beta1") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "google.cloud.errorreporting_v1beta1" + if sys.version_info < (3, 9): + warnings.warn( + "You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning, + ) + if sys.version_info[:2] == (3, 9): + warnings.warn( + f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning, + ) + + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version(_dependency_package) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn( + f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning, + ) + except Exception: + warnings.warn( + "Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/" + ) + __all__ = ( "ErrorGroupServiceAsyncClient", "ErrorStatsServiceAsyncClient", 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 cc4b15df..6102fcda 100644 --- a/google/cloud/errorreporting_v1beta1/services/error_group_service/client.py +++ b/google/cloud/errorreporting_v1beta1/services/error_group_service/client.py @@ -148,6 +148,34 @@ def _get_default_mtls_endpoint(api_endpoint): _DEFAULT_ENDPOINT_TEMPLATE = "clouderrorreporting.{UNIVERSE_DOMAIN}" _DEFAULT_UNIVERSE = "googleapis.com" + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -330,12 +358,8 @@ def get_mtls_endpoint_and_cert_source( ) if client_options is None: client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_client_cert = ErrorGroupServiceClient._use_client_cert_effective() use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) if use_mtls_endpoint not in ("auto", "never", "always"): raise MutualTLSChannelError( "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" @@ -343,7 +367,7 @@ def get_mtls_endpoint_and_cert_source( # Figure out the client cert source to use. client_cert_source = None - if use_client_cert == "true": + if use_client_cert: if client_options.client_cert_source: client_cert_source = client_options.client_cert_source elif mtls.has_default_client_cert_source(): @@ -375,20 +399,14 @@ def _read_environment_variables(): google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT is not any of ["auto", "never", "always"]. """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() + use_client_cert = ErrorGroupServiceClient._use_client_cert_effective() use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) if use_mtls_endpoint not in ("auto", "never", "always"): raise MutualTLSChannelError( "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env + return use_client_cert, use_mtls_endpoint, universe_domain_env @staticmethod def _get_client_cert_source(provided_cert_source, use_cert_flag): 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 dd22c33b..c01492ae 100644 --- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/client.py +++ b/google/cloud/errorreporting_v1beta1/services/error_stats_service/client.py @@ -151,6 +151,34 @@ def _get_default_mtls_endpoint(api_endpoint): _DEFAULT_ENDPOINT_TEMPLATE = "clouderrorreporting.{UNIVERSE_DOMAIN}" _DEFAULT_UNIVERSE = "googleapis.com" + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -333,12 +361,8 @@ def get_mtls_endpoint_and_cert_source( ) if client_options is None: client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_client_cert = ErrorStatsServiceClient._use_client_cert_effective() use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) if use_mtls_endpoint not in ("auto", "never", "always"): raise MutualTLSChannelError( "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" @@ -346,7 +370,7 @@ def get_mtls_endpoint_and_cert_source( # Figure out the client cert source to use. client_cert_source = None - if use_client_cert == "true": + if use_client_cert: if client_options.client_cert_source: client_cert_source = client_options.client_cert_source elif mtls.has_default_client_cert_source(): @@ -378,20 +402,14 @@ def _read_environment_variables(): google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT is not any of ["auto", "never", "always"]. """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() + use_client_cert = ErrorStatsServiceClient._use_client_cert_effective() use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) if use_mtls_endpoint not in ("auto", "never", "always"): raise MutualTLSChannelError( "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env + return use_client_cert, use_mtls_endpoint, universe_domain_env @staticmethod def _get_client_cert_source(provided_cert_source, use_cert_flag): 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 357b85b6..24414830 100644 --- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py +++ b/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py @@ -147,6 +147,34 @@ def _get_default_mtls_endpoint(api_endpoint): _DEFAULT_ENDPOINT_TEMPLATE = "clouderrorreporting.{UNIVERSE_DOMAIN}" _DEFAULT_UNIVERSE = "googleapis.com" + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -312,12 +340,8 @@ def get_mtls_endpoint_and_cert_source( ) if client_options is None: client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_client_cert = ReportErrorsServiceClient._use_client_cert_effective() use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) if use_mtls_endpoint not in ("auto", "never", "always"): raise MutualTLSChannelError( "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" @@ -325,7 +349,7 @@ def get_mtls_endpoint_and_cert_source( # Figure out the client cert source to use. client_cert_source = None - if use_client_cert == "true": + if use_client_cert: if client_options.client_cert_source: client_cert_source = client_options.client_cert_source elif mtls.has_default_client_cert_source(): @@ -357,20 +381,14 @@ def _read_environment_variables(): google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT is not any of ["auto", "never", "always"]. """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() + use_client_cert = ReportErrorsServiceClient._use_client_cert_effective() use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) if use_mtls_endpoint not in ("auto", "never", "always"): raise MutualTLSChannelError( "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env + return use_client_cert, use_mtls_endpoint, universe_domain_env @staticmethod def _get_client_cert_source(provided_cert_source, use_cert_flag): diff --git a/owlbot.py b/librarian.py similarity index 100% rename from owlbot.py rename to librarian.py diff --git a/noxfile.py b/noxfile.py index 35c5330b..74f4f018 100644 --- a/noxfile.py +++ b/noxfile.py @@ -14,6 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +# DO NOT EDIT THIS FILE OUTSIDE OF `.librarian/generator-input` +# The source of truth for this file is `.librarian/generator-input` + + # Generated by synthtool. DO NOT EDIT! from __future__ import absolute_import diff --git a/pytest.ini b/pytest.ini index 4b0c3a75..211cfb0e 100644 --- a/pytest.ini +++ b/pytest.ini @@ -15,6 +15,8 @@ filterwarnings = ignore:.*Create unlinked descriptors is going to go away. Please use get/find descriptors from generated code or query the descriptor_pool.*:DeprecationWarning # Remove tests for `credentials_file` once support for `credentials_file` is removed in `google-auth` ignore:The `credentials_file` argument is deprecated because of a potential security risk:DeprecationWarning + # Remove after support for Python 3.7 is dropped + ignore:You are using a non-supported Python version \(3\.7:FutureWarning # Remove after support for Python 3.8 is dropped ignore:You are using a non-supported Python version \(3\.8:DeprecationWarning ignore:You are using a non-supported Python version \(3\.8:FutureWarning diff --git a/scripts/fixup_errorreporting_v1beta1_keywords.py b/scripts/fixup_errorreporting_v1beta1_keywords.py deleted file mode 100644 index 60f94ffc..00000000 --- a/scripts/fixup_errorreporting_v1beta1_keywords.py +++ /dev/null @@ -1,181 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import argparse -import os -import libcst as cst -import pathlib -import sys -from typing import (Any, Callable, Dict, List, Sequence, Tuple) - - -def partition( - predicate: Callable[[Any], bool], - iterator: Sequence[Any] -) -> Tuple[List[Any], List[Any]]: - """A stable, out-of-place partition.""" - results = ([], []) - - for i in iterator: - results[int(predicate(i))].append(i) - - # Returns trueList, falseList - return results[1], results[0] - - -class errorreportingCallTransformer(cst.CSTTransformer): - CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') - METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { - 'delete_events': ('project_name', ), - 'get_group': ('group_name', ), - 'list_events': ('project_name', 'group_id', 'service_filter', 'time_range', 'page_size', 'page_token', ), - 'list_group_stats': ('project_name', 'group_id', 'service_filter', 'time_range', 'timed_count_duration', 'alignment', 'alignment_time', 'order', 'page_size', 'page_token', ), - 'report_error_event': ('project_name', 'event', ), - 'update_group': ('group', ), - } - - def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: - try: - key = original.func.attr.value - kword_params = self.METHOD_TO_PARAMS[key] - except (AttributeError, KeyError): - # Either not a method from the API or too convoluted to be sure. - return updated - - # If the existing code is valid, keyword args come after positional args. - # Therefore, all positional args must map to the first parameters. - args, kwargs = partition(lambda a: not bool(a.keyword), updated.args) - if any(k.keyword.value == "request" for k in kwargs): - # We've already fixed this file, don't fix it again. - return updated - - kwargs, ctrl_kwargs = partition( - lambda a: a.keyword.value not in self.CTRL_PARAMS, - kwargs - ) - - args, ctrl_args = args[:len(kword_params)], args[len(kword_params):] - ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl)) - for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)) - - request_arg = cst.Arg( - value=cst.Dict([ - cst.DictElement( - cst.SimpleString("'{}'".format(name)), -cst.Element(value=arg.value) - ) - # Note: the args + kwargs looks silly, but keep in mind that - # the control parameters had to be stripped out, and that - # those could have been passed positionally or by keyword. - for name, arg in zip(kword_params, args + kwargs)]), - keyword=cst.Name("request") - ) - - return updated.with_changes( - args=[request_arg] + ctrl_kwargs - ) - - -def fix_files( - in_dir: pathlib.Path, - out_dir: pathlib.Path, - *, - transformer=errorreportingCallTransformer(), -): - """Duplicate the input dir to the output dir, fixing file method calls. - - Preconditions: - * in_dir is a real directory - * out_dir is a real, empty directory - """ - pyfile_gen = ( - pathlib.Path(os.path.join(root, f)) - for root, _, files in os.walk(in_dir) - for f in files if os.path.splitext(f)[1] == ".py" - ) - - for fpath in pyfile_gen: - with open(fpath, 'r') as f: - src = f.read() - - # Parse the code and insert method call fixes. - tree = cst.parse_module(src) - updated = tree.visit(transformer) - - # Create the path and directory structure for the new file. - updated_path = out_dir.joinpath(fpath.relative_to(in_dir)) - updated_path.parent.mkdir(parents=True, exist_ok=True) - - # Generate the updated source file at the corresponding path. - with open(updated_path, 'w') as f: - f.write(updated.code) - - -if __name__ == '__main__': - parser = argparse.ArgumentParser( - description="""Fix up source that uses the errorreporting client library. - -The existing sources are NOT overwritten but are copied to output_dir with changes made. - -Note: This tool operates at a best-effort level at converting positional - parameters in client method calls to keyword based parameters. - Cases where it WILL FAIL include - A) * or ** expansion in a method call. - B) Calls via function or method alias (includes free function calls) - C) Indirect or dispatched calls (e.g. the method is looked up dynamically) - - These all constitute false negatives. The tool will also detect false - positives when an API method shares a name with another method. -""") - parser.add_argument( - '-d', - '--input-directory', - required=True, - dest='input_dir', - help='the input directory to walk for python files to fix up', - ) - parser.add_argument( - '-o', - '--output-directory', - required=True, - dest='output_dir', - help='the directory to output files fixed via un-flattening', - ) - args = parser.parse_args() - input_dir = pathlib.Path(args.input_dir) - output_dir = pathlib.Path(args.output_dir) - if not input_dir.is_dir(): - print( - f"input directory '{input_dir}' does not exist or is not a directory", - file=sys.stderr, - ) - sys.exit(-1) - - if not output_dir.is_dir(): - print( - f"output directory '{output_dir}' does not exist or is not a directory", - file=sys.stderr, - ) - sys.exit(-1) - - if os.listdir(output_dir): - print( - f"output directory '{output_dir}' is not empty", - file=sys.stderr, - ) - sys.exit(-1) - - fix_files(input_dir, output_dir) diff --git a/setup.py b/setup.py index c80d2b25..06588170 100644 --- a/setup.py +++ b/setup.py @@ -13,6 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # + +# DO NOT EDIT THIS FILE OUTSIDE OF `.librarian/generator-input` +# The source of truth for this file is `.librarian/generator-input` + import io import os 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 67adff43..c98fd691 100644 --- a/tests/unit/gapic/errorreporting_v1beta1/test_error_group_service.py +++ b/tests/unit/gapic/errorreporting_v1beta1/test_error_group_service.py @@ -168,12 +168,19 @@ def test__read_environment_variables(): with mock.patch.dict( os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} ): - with pytest.raises(ValueError) as excinfo: - ErrorGroupServiceClient._read_environment_variables() - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with pytest.raises(ValueError) as excinfo: + ErrorGroupServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + else: + assert ErrorGroupServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): assert ErrorGroupServiceClient._read_environment_variables() == ( @@ -212,6 +219,105 @@ def test__read_environment_variables(): ) +def test_use_client_cert_effective(): + # Test case 1: Test when `should_use_client_cert` returns True. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=True + ): + assert ErrorGroupServiceClient._use_client_cert_effective() is True + + # Test case 2: Test when `should_use_client_cert` returns False. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should NOT be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=False + ): + assert ErrorGroupServiceClient._use_client_cert_effective() is False + + # Test case 3: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert ErrorGroupServiceClient._use_client_cert_effective() is True + + # Test case 4: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} + ): + assert ErrorGroupServiceClient._use_client_cert_effective() is False + + # Test case 5: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): + assert ErrorGroupServiceClient._use_client_cert_effective() is True + + # Test case 6: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} + ): + assert ErrorGroupServiceClient._use_client_cert_effective() is False + + # Test case 7: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): + assert ErrorGroupServiceClient._use_client_cert_effective() is True + + # Test case 8: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} + ): + assert ErrorGroupServiceClient._use_client_cert_effective() is False + + # Test case 9: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set. + # In this case, the method should return False, which is the default value. + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, clear=True): + assert ErrorGroupServiceClient._use_client_cert_effective() is False + + # Test case 10: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should raise a ValueError as the environment variable must be either + # "true" or "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + with pytest.raises(ValueError): + ErrorGroupServiceClient._use_client_cert_effective() + + # Test case 11: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should return False as the environment variable is set to an invalid value. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + assert ErrorGroupServiceClient._use_client_cert_effective() is False + + # Test case 12: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also, + # the GOOGLE_API_CONFIG environment variable is unset. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}): + with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}): + assert ErrorGroupServiceClient._use_client_cert_effective() is False + + def test__get_client_cert_source(): mock_provided_cert_source = mock.Mock() mock_default_cert_source = mock.Mock() @@ -585,17 +691,6 @@ def test_error_group_service_client_client_options( == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" ) - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError) as excinfo: - client = client_class(transport=transport_name) - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - # Check the case quota_project_id is provided options = client_options.ClientOptions(quota_project_id="octopus") with mock.patch.object(transport_class, "__init__") as patched: @@ -831,6 +926,119 @@ def test_error_group_service_client_get_mtls_endpoint_and_cert_source(client_cla assert api_endpoint == mock_api_endpoint assert cert_source is None + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "Unsupported". + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, + api_endpoint=mock_api_endpoint, + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset. + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, + api_endpoint=mock_api_endpoint, + ) + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is expected_cert_source + + # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, + api_endpoint=mock_api_endpoint, + ) + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is expected_cert_source + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() @@ -881,18 +1089,6 @@ def test_error_group_service_client_get_mtls_endpoint_and_cert_source(client_cla == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" ) - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - @pytest.mark.parametrize( "client_class", [ErrorGroupServiceClient, ErrorGroupServiceAsyncClient] @@ -3090,6 +3286,7 @@ def test_error_group_service_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize( "transport_class", [ 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 0b1bdc25..f47cbc80 100644 --- a/tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py +++ b/tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py @@ -171,12 +171,19 @@ def test__read_environment_variables(): with mock.patch.dict( os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} ): - with pytest.raises(ValueError) as excinfo: - ErrorStatsServiceClient._read_environment_variables() - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with pytest.raises(ValueError) as excinfo: + ErrorStatsServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + else: + assert ErrorStatsServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): assert ErrorStatsServiceClient._read_environment_variables() == ( @@ -215,6 +222,105 @@ def test__read_environment_variables(): ) +def test_use_client_cert_effective(): + # Test case 1: Test when `should_use_client_cert` returns True. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=True + ): + assert ErrorStatsServiceClient._use_client_cert_effective() is True + + # Test case 2: Test when `should_use_client_cert` returns False. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should NOT be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=False + ): + assert ErrorStatsServiceClient._use_client_cert_effective() is False + + # Test case 3: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert ErrorStatsServiceClient._use_client_cert_effective() is True + + # Test case 4: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} + ): + assert ErrorStatsServiceClient._use_client_cert_effective() is False + + # Test case 5: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): + assert ErrorStatsServiceClient._use_client_cert_effective() is True + + # Test case 6: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} + ): + assert ErrorStatsServiceClient._use_client_cert_effective() is False + + # Test case 7: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): + assert ErrorStatsServiceClient._use_client_cert_effective() is True + + # Test case 8: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} + ): + assert ErrorStatsServiceClient._use_client_cert_effective() is False + + # Test case 9: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set. + # In this case, the method should return False, which is the default value. + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, clear=True): + assert ErrorStatsServiceClient._use_client_cert_effective() is False + + # Test case 10: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should raise a ValueError as the environment variable must be either + # "true" or "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + with pytest.raises(ValueError): + ErrorStatsServiceClient._use_client_cert_effective() + + # Test case 11: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should return False as the environment variable is set to an invalid value. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + assert ErrorStatsServiceClient._use_client_cert_effective() is False + + # Test case 12: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also, + # the GOOGLE_API_CONFIG environment variable is unset. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}): + with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}): + assert ErrorStatsServiceClient._use_client_cert_effective() is False + + def test__get_client_cert_source(): mock_provided_cert_source = mock.Mock() mock_default_cert_source = mock.Mock() @@ -588,17 +694,6 @@ def test_error_stats_service_client_client_options( == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" ) - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError) as excinfo: - client = client_class(transport=transport_name) - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - # Check the case quota_project_id is provided options = client_options.ClientOptions(quota_project_id="octopus") with mock.patch.object(transport_class, "__init__") as patched: @@ -834,6 +929,119 @@ def test_error_stats_service_client_get_mtls_endpoint_and_cert_source(client_cla assert api_endpoint == mock_api_endpoint assert cert_source is None + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "Unsupported". + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, + api_endpoint=mock_api_endpoint, + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset. + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, + api_endpoint=mock_api_endpoint, + ) + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is expected_cert_source + + # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, + api_endpoint=mock_api_endpoint, + ) + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is expected_cert_source + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() @@ -884,18 +1092,6 @@ def test_error_stats_service_client_get_mtls_endpoint_and_cert_source(client_cla == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" ) - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - @pytest.mark.parametrize( "client_class", [ErrorStatsServiceClient, ErrorStatsServiceAsyncClient] @@ -4352,6 +4548,7 @@ def test_error_stats_service_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize( "transport_class", [ 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 9ac7c004..45def7bc 100644 --- a/tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py +++ b/tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py @@ -171,12 +171,19 @@ def test__read_environment_variables(): with mock.patch.dict( os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} ): - with pytest.raises(ValueError) as excinfo: - ReportErrorsServiceClient._read_environment_variables() - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with pytest.raises(ValueError) as excinfo: + ReportErrorsServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + else: + assert ReportErrorsServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): assert ReportErrorsServiceClient._read_environment_variables() == ( @@ -215,6 +222,105 @@ def test__read_environment_variables(): ) +def test_use_client_cert_effective(): + # Test case 1: Test when `should_use_client_cert` returns True. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=True + ): + assert ReportErrorsServiceClient._use_client_cert_effective() is True + + # Test case 2: Test when `should_use_client_cert` returns False. + # We mock the `should_use_client_cert` function to simulate a scenario where + # the google-auth library supports automatic mTLS and determines that a + # client certificate should NOT be used. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch( + "google.auth.transport.mtls.should_use_client_cert", return_value=False + ): + assert ReportErrorsServiceClient._use_client_cert_effective() is False + + # Test case 3: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert ReportErrorsServiceClient._use_client_cert_effective() is True + + # Test case 4: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} + ): + assert ReportErrorsServiceClient._use_client_cert_effective() is False + + # Test case 5: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): + assert ReportErrorsServiceClient._use_client_cert_effective() is True + + # Test case 6: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} + ): + assert ReportErrorsServiceClient._use_client_cert_effective() is False + + # Test case 7: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): + assert ReportErrorsServiceClient._use_client_cert_effective() is True + + # Test case 8: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} + ): + assert ReportErrorsServiceClient._use_client_cert_effective() is False + + # Test case 9: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set. + # In this case, the method should return False, which is the default value. + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, clear=True): + assert ReportErrorsServiceClient._use_client_cert_effective() is False + + # Test case 10: Test when `should_use_client_cert` is unavailable and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should raise a ValueError as the environment variable must be either + # "true" or "false". + if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + with pytest.raises(ValueError): + ReportErrorsServiceClient._use_client_cert_effective() + + # Test case 11: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. + # The method should return False as the environment variable is set to an invalid value. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} + ): + assert ReportErrorsServiceClient._use_client_cert_effective() is False + + # Test case 12: Test when `should_use_client_cert` is available and the + # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also, + # the GOOGLE_API_CONFIG environment variable is unset. + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}): + with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}): + assert ReportErrorsServiceClient._use_client_cert_effective() is False + + def test__get_client_cert_source(): mock_provided_cert_source = mock.Mock() mock_default_cert_source = mock.Mock() @@ -602,17 +708,6 @@ def test_report_errors_service_client_client_options( == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" ) - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError) as excinfo: - client = client_class(transport=transport_name) - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - # Check the case quota_project_id is provided options = client_options.ClientOptions(quota_project_id="octopus") with mock.patch.object(transport_class, "__init__") as patched: @@ -848,6 +943,119 @@ def test_report_errors_service_client_get_mtls_endpoint_and_cert_source(client_c assert api_endpoint == mock_api_endpoint assert cert_source is None + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "Unsupported". + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, + api_endpoint=mock_api_endpoint, + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset. + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, + api_endpoint=mock_api_endpoint, + ) + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is expected_cert_source + + # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). + test_cases = [ + ( + # With workloads present in config, mTLS is enabled. + { + "version": 1, + "cert_configs": { + "workload": { + "cert_path": "path/to/cert/file", + "key_path": "path/to/key/file", + } + }, + }, + mock_client_cert_source, + ), + ( + # With workloads not present in config, mTLS is disabled. + { + "version": 1, + "cert_configs": {}, + }, + None, + ), + ] + if hasattr(google.auth.transport.mtls, "should_use_client_cert"): + for config_data, expected_cert_source in test_cases: + env = os.environ.copy() + env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") + with mock.patch.dict(os.environ, env, clear=True): + config_filename = "mock_certificate_config.json" + config_file_content = json.dumps(config_data) + m = mock.mock_open(read_data=config_file_content) + with mock.patch("builtins.open", m): + with mock.patch.dict( + os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} + ): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, + api_endpoint=mock_api_endpoint, + ) + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is expected_cert_source + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() @@ -898,18 +1106,6 @@ def test_report_errors_service_client_get_mtls_endpoint_and_cert_source(client_c == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" ) - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - @pytest.mark.parametrize( "client_class", [ReportErrorsServiceClient, ReportErrorsServiceAsyncClient] @@ -2489,6 +2685,7 @@ def test_report_errors_service_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize( "transport_class", [ From 125c35d3d5bf333920cad3d7811dbd49f1fdcc7c Mon Sep 17 00:00:00 2001 From: Daniel Sanche Date: Tue, 16 Dec 2025 13:38:43 -0800 Subject: [PATCH 06/11] chore: librarian release pull request: 20251216T123125Z (#718) PR created by the Librarian CLI to initialize a release. Merging this PR will auto trigger a release. Librarian Version: v0.7.0 Language Image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209
google-cloud-error-reporting: 1.14.0 ## [1.14.0](https://github.com/googleapis/python-error-reporting/compare/v1.13.0...v1.14.0) (2025-12-16) ### Features * support mTLS certificates when available (#717) ([7e99258b](https://github.com/googleapis/python-error-reporting/commit/7e99258b))
--- .librarian/state.yaml | 2 +- CHANGELOG.md | 7 +++++++ google/cloud/error_reporting/gapic_version.py | 2 +- google/cloud/errorreporting_v1beta1/gapic_version.py | 2 +- ...tadata_google.devtools.clouderrorreporting.v1beta1.json | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index c12cabcf..85f59352 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,7 +1,7 @@ image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209 libraries: - id: google-cloud-error-reporting - version: 1.13.0 + version: 1.14.0 last_generated_commit: cf0434f4bd20618db60ddd16a1e7db2c0dfb9158 apis: - path: google/devtools/clouderrorreporting/v1beta1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f9a8318..dca4a7fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://pypi.org/project/google-cloud-error-reporting/#history +## [1.14.0](https://github.com/googleapis/python-error-reporting/compare/v1.13.0...v1.14.0) (2025-12-16) + + +### Features + +* support mTLS certificates when available (#717) ([7e99258b41ddef55b63c70c7e31afced4ab30103](https://github.com/googleapis/python-error-reporting/commit/7e99258b41ddef55b63c70c7e31afced4ab30103)) + ## [1.13.0](https://github.com/googleapis/python-error-reporting/compare/v1.12.0...v1.13.0) (2025-11-12) diff --git a/google/cloud/error_reporting/gapic_version.py b/google/cloud/error_reporting/gapic_version.py index 1fc1b24b..624a2e53 100644 --- a/google/cloud/error_reporting/gapic_version.py +++ b/google/cloud/error_reporting/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.13.0" # {x-release-please-version} +__version__ = "1.14.0" # {x-release-please-version} diff --git a/google/cloud/errorreporting_v1beta1/gapic_version.py b/google/cloud/errorreporting_v1beta1/gapic_version.py index 4cccf771..750bf9a8 100644 --- a/google/cloud/errorreporting_v1beta1/gapic_version.py +++ b/google/cloud/errorreporting_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.13.0" # {x-release-please-version} +__version__ = "1.14.0" # {x-release-please-version} diff --git a/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json b/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json index 1d772531..6fff713c 100644 --- a/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json +++ b/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-error-reporting", - "version": "1.13.0" + "version": "1.14.0" }, "snippets": [ { From cc09613cf1aa078154692ac66c1ae77591f1d3ad Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Wed, 21 Jan 2026 16:27:41 -0500 Subject: [PATCH 07/11] chore: remove api-logging team (#720) Removing @googleapis/api-logging, @googleapis/api-logging-partners, and @googleapis/api-logging-reviewers. Replaced with @googleapis/yoshi-python in metadata and blunderbuss. b/476446922 --- .github/CODEOWNERS | 8 ++++---- .github/blunderbuss.yml | 9 +++------ .librarian/generator-input/.repo-metadata.json | 2 +- .repo-metadata.json | 2 +- pytest.ini | 2 ++ 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0738e11e..b3aefa82 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -5,8 +5,8 @@ # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax # Note: This file is autogenerated. To make changes to the codeowner team, please update .repo-metadata.json. -# @googleapis/yoshi-python @googleapis/api-logging @googleapis/api-logging-partners are the default owners for changes in this repo -* @googleapis/yoshi-python @googleapis/api-logging @googleapis/api-logging-partners +# @googleapis/yoshi-python are the default owners for changes in this repo +* @googleapis/yoshi-python -# @googleapis/python-samples-reviewers @googleapis/api-logging @googleapis/api-logging-partners are the default owners for samples changes -/samples/ @googleapis/python-samples-reviewers @googleapis/api-logging @googleapis/api-logging-partners +# @googleapis/python-samples-reviewers are the default owners for samples changes +/samples/ @googleapis/python-samples-reviewers diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index d5f69b10..dec2056f 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -4,17 +4,14 @@ # Note: This file is autogenerated. To make changes to the assignee # team, please update `codeowner_team` in `.repo-metadata.json`. assign_issues: - - googleapis/api-logging - - googleapis/api-logging-partners + - googleapis/yoshi-python assign_issues_by: - labels: - "samples" to: - googleapis/python-samples-reviewers - - googleapis/api-logging - - googleapis/api-logging-partners + - googleapis/yoshi-python assign_prs: - - googleapis/api-logging - - googleapis/api-logging-partners + - googleapis/yoshi-python diff --git a/.librarian/generator-input/.repo-metadata.json b/.librarian/generator-input/.repo-metadata.json index e032093f..5161e69d 100644 --- a/.librarian/generator-input/.repo-metadata.json +++ b/.librarian/generator-input/.repo-metadata.json @@ -11,7 +11,7 @@ "distribution_name": "google-cloud-error-reporting", "api_id": "clouderrorreporting.googleapis.com", "requires_billing": false, - "codeowner_team": "@googleapis/api-logging @googleapis/api-logging-partners", + "codeowner_team": "@googleapis/yoshi-python", "default_version": "v1beta1", "api_shortname": "clouderrorreporting", "api_description": "counts, analyzes and aggregates the crashes in your running cloud services. A centralized error management interface displays the results with sorting and filtering capabilities. A dedicated view shows the error details: time chart, occurrences, affected user count, first and last seen dates and a cleaned exception stack trace. Opt-in to receive email and mobile alerts on new errors." diff --git a/.repo-metadata.json b/.repo-metadata.json index e032093f..5161e69d 100644 --- a/.repo-metadata.json +++ b/.repo-metadata.json @@ -11,7 +11,7 @@ "distribution_name": "google-cloud-error-reporting", "api_id": "clouderrorreporting.googleapis.com", "requires_billing": false, - "codeowner_team": "@googleapis/api-logging @googleapis/api-logging-partners", + "codeowner_team": "@googleapis/yoshi-python", "default_version": "v1beta1", "api_shortname": "clouderrorreporting", "api_description": "counts, analyzes and aggregates the crashes in your running cloud services. A centralized error management interface displays the results with sorting and filtering capabilities. A dedicated view shows the error details: time chart, occurrences, affected user count, first and last seen dates and a cleaned exception stack trace. Opt-in to receive email and mobile alerts on new errors." diff --git a/pytest.ini b/pytest.ini index 211cfb0e..f975ca75 100644 --- a/pytest.ini +++ b/pytest.ini @@ -24,3 +24,5 @@ filterwarnings = ignore:You are using a Python version \(3\.9:FutureWarning # Remove after support for Python 3.10 is dropped ignore:.*You are using a Python version \(3\.10:FutureWarning + ignore:.*Please upgrade to the latest Python version.*:FutureWarning + ignore:(?s).*using a Python version.*past its end of life.*:FutureWarning From 4d6b27b5776c64ac35083363454f3b53b6d652d7 Mon Sep 17 00:00:00 2001 From: gurusai-voleti Date: Fri, 13 Feb 2026 20:38:48 +0530 Subject: [PATCH 08/11] chore: Migrate gsutil usage to gcloud storage (#722) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Automated: Migrate {target_path} from gsutil to gcloud storage This CL is part of the on going effort to migrate from the legacy `gsutil` tool to the new and improved `gcloud storage` command-line interface. `gcloud storage` is the recommended and modern tool for interacting with Google Cloud Storage, offering better performance, unified authentication, and a more consistent command structure with other `gcloud` components. 🚀 ### Automation Details This change was **generated automatically** by an agent that targets users of `gsutil`. The transformations applied are based on the [gsutil to gcloud storage migration guide](http://go/gsutil-gcloud-storage-migration-guide). ### ⚠️ Action Required: Please Review and Test Carefully While we have based the automation on the migration guide, every use case is unique. **It is crucial that you thoroughly test these changes in environments appropriate to your use-case before merging.** Be aware of potential differences between `gsutil` and `gcloud storage` that could impact your workflows. For instance, the structure of command output may have changed, requiring updates to any scripts that parse it. Similarly, command behavior can differ subtly; the `gcloud storage rsync` command has a different file deletion logic than `gsutil rsync`, which could lead to unintended file deletions. Our migration guides can help guide you through a list of mappings and some notable differences between the two tools. Standard presubmit tests are run as part of this CL's workflow. **If you need to target an additional test workflow or require assistance with testing, please let us know.** Please verify that all your Cloud Storage operations continue to work as expected to avoid any potential disruptions in production. ### Support and Collaboration The `GCS CLI` team is here to help! If you encounter any issues, have a complex use case that this automated change doesn't cover, or face any other blockers, please don't hesitate to reach out. We are happy to work with you to test and adjust these changes as needed. **Contact:** `gcs-cli-hyd@google.com` We appreciate your partnership in this important migration effort! #gsutil-migration --- .kokoro/trampoline_v2.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.kokoro/trampoline_v2.sh b/.kokoro/trampoline_v2.sh index 35fa5292..d03f92df 100755 --- a/.kokoro/trampoline_v2.sh +++ b/.kokoro/trampoline_v2.sh @@ -26,8 +26,8 @@ # To run this script, first download few files from gcs to /dev/shm. # (/dev/shm is passed into the container as KOKORO_GFILE_DIR). # -# gsutil cp gs://cloud-devrel-kokoro-resources/python-docs-samples/secrets_viewer_service_account.json /dev/shm -# gsutil cp gs://cloud-devrel-kokoro-resources/python-docs-samples/automl_secrets.txt /dev/shm +# gcloud storage cp gs://cloud-devrel-kokoro-resources/python-docs-samples/secrets_viewer_service_account.json /dev/shm +# gcloud storage cp gs://cloud-devrel-kokoro-resources/python-docs-samples/automl_secrets.txt /dev/shm # # Then run the script. # .kokoro/trampoline_v2.sh From 36c2a337575c4b192c5d8d092c39f94e8724e546 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 13 Feb 2026 15:23:35 +0000 Subject: [PATCH 09/11] chore(deps): update all dependencies (#719) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/checkout](https://redirect.github.com/actions/checkout) | action | major | `v4` → `v6` | | [actions/setup-python](https://redirect.github.com/actions/setup-python) | action | major | `v5` → `v6` | | [python](https://redirect.github.com/actions/python-versions) | uses-with | minor | `3.10` → `3.14` | --- ### Release Notes
actions/checkout (actions/checkout) ### [`v6`](https://redirect.github.com/actions/checkout/compare/v5...v6) [Compare Source](https://redirect.github.com/actions/checkout/compare/v5...v6) ### [`v5`](https://redirect.github.com/actions/checkout/compare/v4...v5) [Compare Source](https://redirect.github.com/actions/checkout/compare/v4...v5)
actions/setup-python (actions/setup-python) ### [`v6`](https://redirect.github.com/actions/setup-python/compare/v5...v6) [Compare Source](https://redirect.github.com/actions/setup-python/compare/v5...v6)
actions/python-versions (python) ### [`v3.14.2`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.2-20014991423): 3.14.2 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.14.1-19879739908...3.14.2-20014991423) Python 3.14.2 ### [`v3.14.1`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.1-19879739908): 3.14.1 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.14.0-18313368925...3.14.1-19879739908) Python 3.14.1 ### [`v3.14.0`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.0-18313368925): 3.14.0 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.13.11-20014977833...3.14.0-18313368925) Python 3.14.0 ### [`v3.13.11`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.11-20014977833): 3.13.11 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.13.10-19879712315...3.13.11-20014977833) Python 3.13.11 ### [`v3.13.10`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.10-19879712315): 3.13.10 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.13.9-18515951191...3.13.10-19879712315) Python 3.13.10 ### [`v3.13.9`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.9-18515951191): 3.13.9 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.13.8-18331000654...3.13.9-18515951191) Python 3.13.9 ### [`v3.13.8`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.8-18331000654): 3.13.8 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.13.7-16980743123...3.13.8-18331000654) Python 3.13.8 ### [`v3.13.7`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.7-16980743123): 3.13.7 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.13.6-16792117939...3.13.7-16980743123) Python 3.13.7 ### [`v3.13.6`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.6-16792117939): 3.13.6 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.13.5-15601068749...3.13.6-16792117939) Python 3.13.6 ### [`v3.13.5`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.5-15601068749): 3.13.5 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.13.4-15433317575...3.13.5-15601068749) Python 3.13.5 ### [`v3.13.4`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.4-15433317575): 3.13.4 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.13.3-14344076652...3.13.4-15433317575) Python 3.13.4 ### [`v3.13.3`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.3-14344076652): 3.13.3 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.13.2-13708744326...3.13.3-14344076652) Python 3.13.3 ### [`v3.13.2`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.2-13708744326): 3.13.2 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.13.1-13437882550...3.13.2-13708744326) Python 3.13.2 ### [`v3.13.1`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.1-13437882550): 3.13.1 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.13.0-13707372259...3.13.1-13437882550) Python 3.13.1 ### [`v3.13.0`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.0-13707372259): 3.13.0 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.12.12-18393146713...3.13.0-13707372259) Python 3.13.0 ### [`v3.12.12`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.12-18393146713): 3.12.12 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.12.11-15433310049...3.12.12-18393146713) Python 3.12.12 ### [`v3.12.11`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.11-15433310049): 3.12.11 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.12.10-14343898437...3.12.11-15433310049) Python 3.12.11 ### [`v3.12.10`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.10-14343898437): 3.12.10 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.12.9-13149478207...3.12.10-14343898437) Python 3.12.10 ### [`v3.12.9`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.9-13149478207): 3.12.9 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.12.8-12154062663...3.12.9-13149478207) Python 3.12.9 ### [`v3.12.8`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.8-12154062663): 3.12.8 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.12.7-11128208086...3.12.8-12154062663) Python 3.12.8 ### [`v3.12.7`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.7-11128208086): 3.12.7 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.12.6-10765725458...3.12.7-11128208086) Python 3.12.7 ### [`v3.12.6`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.6-10765725458): 3.12.6 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.12.5-10375840348...3.12.6-10765725458) Python 3.12.6 ### [`v3.12.5`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.5-10375840348): 3.12.5 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.12.4-9947065640...3.12.5-10375840348) Python 3.12.5 ### [`v3.12.4`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.4-9947065640): 3.12.4 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.12.3-11057844995...3.12.4-9947065640) Python 3.12.4 ### [`v3.12.3`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.3-11057844995): 3.12.3 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.12.2-11057786931...3.12.3-11057844995) Python 3.12.3 ### [`v3.12.2`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.2-11057786931): 3.12.2 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.12.1-11057762749...3.12.2-11057786931) Python 3.12.2 ### [`v3.12.1`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.1-11057762749): 3.12.1 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.12.0-11057302691...3.12.1-11057762749) Python 3.12.1 ### [`v3.12.0`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.0-11057302691): 3.12.0 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.14-18393181605...3.12.0-11057302691) Python 3.12.0 ### [`v3.11.14`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.14-18393181605): 3.11.14 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.13-15433298024...3.11.14-18393181605) Python 3.11.14 ### [`v3.11.13`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.13-15433298024): 3.11.13 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.12-14343939122...3.11.13-15433298024) Python 3.11.13 ### [`v3.11.12`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.12-14343939122): 3.11.12 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.11-12160100664...3.11.12-14343939122) Python 3.11.12 ### [`v3.11.11`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.11-12160100664): 3.11.11 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.10-10765870205...3.11.11-12160100664) Python 3.11.11 ### [`v3.11.10`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.10-10765870205): 3.11.10 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.9-9947079978...3.11.10-10765870205) Python 3.11.10 ### [`v3.11.9`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.9-9947079978): 3.11.9 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.8-11113201752...3.11.9-9947079978) Python 3.11.9 ### [`v3.11.8`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.8-11113201752): 3.11.8 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.7-11113197120...3.11.8-11113201752) Python 3.11.8 ### [`v3.11.7`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.7-11113197120): 3.11.7 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.6-11113179737...3.11.7-11113197120) Python 3.11.7 ### [`v3.11.6`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.6-11113179737): 3.11.6 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.5-11113174019...3.11.6-11113179737) Python 3.11.6 ### [`v3.11.5`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.5-11113174019): 3.11.5 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.4-11113170699...3.11.5-11113174019) Python 3.11.5 ### [`v3.11.4`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.4-11113170699): 3.11.4 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.3-11059198104...3.11.4-11113170699) Python 3.11.4 ### [`v3.11.3`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.3-11059198104): 3.11.3 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.2-11059137522...3.11.3-11059198104) Python 3.11.3 ### [`v3.11.2`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.2-11059137522): 3.11.2 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.1-11058799881...3.11.2-11059137522) Python 3.11.2 ### [`v3.11.1`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.1-11058799881): 3.11.1 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.11.0-11058707212...3.11.1-11058799881) Python 3.11.1 ### [`v3.11.0`](https://redirect.github.com/actions/python-versions/releases/tag/3.11.0-11058707212): 3.11.0 [Compare Source](https://redirect.github.com/actions/python-versions/compare/3.10.19-18393196481...3.11.0-11058707212) Python 3.11.0
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/googleapis/python-error-reporting). --------- Co-authored-by: Daniel Sanche Co-authored-by: Anthonios Partheniou --- .github/workflows/docs.yml | 8 ++++---- .github/workflows/lint.yml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 2833fe98..c5ee9883 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -8,9 +8,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.10" - name: Install nox @@ -24,9 +24,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.10" - name: Install nox diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 3ed755f0..a5293348 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,9 +8,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.14" - name: Install nox From 403fa48a2ed19de10258d27390807ee5290c03d3 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Fri, 13 Feb 2026 10:53:03 -0500 Subject: [PATCH 10/11] chore: librarian update image pull request: 20260213T152756Z (#727) feat: update image to us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:a38add811f7f139d6a385b22d283ad09ef305b8cf50382ef62f0ce690787f021 Fixes b/483054727 --- .librarian/state.yaml | 2 +- docs/conf.py | 39 +++++++++++++++++-- .../error_group_service/async_client.py | 10 ++++- .../error_group_service/transports/base.py | 11 ++++-- .../error_stats_service/async_client.py | 10 ++++- .../error_stats_service/transports/base.py | 11 ++++-- .../report_errors_service/async_client.py | 10 ++++- .../report_errors_service/transports/base.py | 11 ++++-- .../errorreporting_v1beta1/types/common.py | 2 +- .../types/error_stats_service.py | 4 +- .../types/report_errors_service.py | 2 +- mypy.ini | 14 ++++++- testing/constraints-3.10.txt | 2 + testing/constraints-3.11.txt | 2 + testing/constraints-3.12.txt | 2 + testing/constraints-3.9.txt | 2 + .../test_error_group_service.py | 1 + .../test_error_stats_service.py | 5 ++- .../test_report_errors_service.py | 3 +- 19 files changed, 113 insertions(+), 30 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 85f59352..7342d2e6 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,4 +1,4 @@ -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209 +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:a38add811f7f139d6a385b22d283ad09ef305b8cf50382ef62f0ce690787f021 libraries: - id: google-cloud-error-reporting version: 1.14.0 diff --git a/docs/conf.py b/docs/conf.py index 6a191f48..ef62ba33 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,8 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# -# +## # google-cloud-error-reporting documentation build configuration file # # This file is execfile()d with the current directory set to its @@ -25,9 +24,12 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys +import logging import os import shlex +import sys +import logging +from typing import Any # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -383,3 +385,34 @@ napoleon_use_ivar = False napoleon_use_param = True napoleon_use_rtype = True + + +# Setup for sphinx behaviors such as warning filters. +class UnexpectedUnindentFilter(logging.Filter): + """Filter out warnings about unexpected unindentation following bullet lists.""" + + def filter(self, record: logging.LogRecord) -> bool: + """Filter the log record. + + Args: + record (logging.LogRecord): The log record. + + Returns: + bool: False to suppress the warning, True to allow it. + """ + msg = record.getMessage() + if "Bullet list ends without a blank line" in msg: + return False + return True + + +def setup(app: Any) -> None: + """Setup the Sphinx application. + + Args: + app (Any): The Sphinx application. + """ + # Sphinx's logger is hierarchical. Adding a filter to the + # root 'sphinx' logger will catch warnings from all sub-loggers. + logger = logging.getLogger("sphinx") + logger.addFilter(UnexpectedUnindentFilter()) 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 3e9cf737..4074530e 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 @@ -115,7 +115,10 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): Returns: ErrorGroupServiceAsyncClient: The constructed client. """ - return ErrorGroupServiceClient.from_service_account_info.__func__(ErrorGroupServiceAsyncClient, info, *args, **kwargs) # type: ignore + sa_info_func = ( + ErrorGroupServiceClient.from_service_account_info.__func__ # type: ignore + ) + return sa_info_func(ErrorGroupServiceAsyncClient, info, *args, **kwargs) @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): @@ -131,7 +134,10 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): Returns: ErrorGroupServiceAsyncClient: The constructed client. """ - return ErrorGroupServiceClient.from_service_account_file.__func__(ErrorGroupServiceAsyncClient, filename, *args, **kwargs) # type: ignore + sa_file_func = ( + ErrorGroupServiceClient.from_service_account_file.__func__ # type: ignore + ) + return sa_file_func(ErrorGroupServiceAsyncClient, filename, *args, **kwargs) from_service_account_json = from_service_account_file 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 e079b904..4ba98770 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 @@ -84,8 +84,6 @@ def __init__( be used for service account credentials. """ - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - # Save the scopes. self._scopes = scopes if not hasattr(self, "_ignore_credentials"): @@ -100,11 +98,16 @@ def __init__( if credentials_file is not None: credentials, _ = google.auth.load_credentials_from_file( - credentials_file, **scopes_kwargs, quota_project_id=quota_project_id + credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, ) elif credentials is None and not self._ignore_credentials: credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id + scopes=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, ) # Don't apply audience if the credentials file passed from user. if hasattr(credentials, "with_gdch_audience"): 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 f588025e..b0b9b735 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 @@ -118,7 +118,10 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): Returns: ErrorStatsServiceAsyncClient: The constructed client. """ - return ErrorStatsServiceClient.from_service_account_info.__func__(ErrorStatsServiceAsyncClient, info, *args, **kwargs) # type: ignore + sa_info_func = ( + ErrorStatsServiceClient.from_service_account_info.__func__ # type: ignore + ) + return sa_info_func(ErrorStatsServiceAsyncClient, info, *args, **kwargs) @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): @@ -134,7 +137,10 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): Returns: ErrorStatsServiceAsyncClient: The constructed client. """ - return ErrorStatsServiceClient.from_service_account_file.__func__(ErrorStatsServiceAsyncClient, filename, *args, **kwargs) # type: ignore + sa_file_func = ( + ErrorStatsServiceClient.from_service_account_file.__func__ # type: ignore + ) + return sa_file_func(ErrorStatsServiceAsyncClient, filename, *args, **kwargs) from_service_account_json = from_service_account_file 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 7cc2de51..8d5312e3 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 @@ -83,8 +83,6 @@ def __init__( be used for service account credentials. """ - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - # Save the scopes. self._scopes = scopes if not hasattr(self, "_ignore_credentials"): @@ -99,11 +97,16 @@ def __init__( if credentials_file is not None: credentials, _ = google.auth.load_credentials_from_file( - credentials_file, **scopes_kwargs, quota_project_id=quota_project_id + credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, ) elif credentials is None and not self._ignore_credentials: credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id + scopes=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, ) # Don't apply audience if the credentials file passed from user. if hasattr(credentials, "with_gdch_audience"): 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 f07f8629..d91c885b 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 @@ -110,7 +110,10 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): Returns: ReportErrorsServiceAsyncClient: The constructed client. """ - return ReportErrorsServiceClient.from_service_account_info.__func__(ReportErrorsServiceAsyncClient, info, *args, **kwargs) # type: ignore + sa_info_func = ( + ReportErrorsServiceClient.from_service_account_info.__func__ # type: ignore + ) + return sa_info_func(ReportErrorsServiceAsyncClient, info, *args, **kwargs) @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): @@ -126,7 +129,10 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): Returns: ReportErrorsServiceAsyncClient: The constructed client. """ - return ReportErrorsServiceClient.from_service_account_file.__func__(ReportErrorsServiceAsyncClient, filename, *args, **kwargs) # type: ignore + sa_file_func = ( + ReportErrorsServiceClient.from_service_account_file.__func__ # type: ignore + ) + return sa_file_func(ReportErrorsServiceAsyncClient, filename, *args, **kwargs) from_service_account_json = from_service_account_file 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 f9599b51..4a121c36 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 @@ -83,8 +83,6 @@ def __init__( be used for service account credentials. """ - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - # Save the scopes. self._scopes = scopes if not hasattr(self, "_ignore_credentials"): @@ -99,11 +97,16 @@ def __init__( if credentials_file is not None: credentials, _ = google.auth.load_credentials_from_file( - credentials_file, **scopes_kwargs, quota_project_id=quota_project_id + credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, ) elif credentials is None and not self._ignore_credentials: credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id + scopes=scopes, + quota_project_id=quota_project_id, + default_scopes=self.AUTH_SCOPES, ) # Don't apply audience if the credentials file passed from user. if hasattr(credentials, "with_gdch_audience"): diff --git a/google/cloud/errorreporting_v1beta1/types/common.py b/google/cloud/errorreporting_v1beta1/types/common.py index 84320a89..d50ed7f7 100644 --- a/google/cloud/errorreporting_v1beta1/types/common.py +++ b/google/cloud/errorreporting_v1beta1/types/common.py @@ -19,7 +19,7 @@ import proto # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore __protobuf__ = proto.module( diff --git a/google/cloud/errorreporting_v1beta1/types/error_stats_service.py b/google/cloud/errorreporting_v1beta1/types/error_stats_service.py index 0285d9a8..5418d33e 100644 --- a/google/cloud/errorreporting_v1beta1/types/error_stats_service.py +++ b/google/cloud/errorreporting_v1beta1/types/error_stats_service.py @@ -20,8 +20,8 @@ import proto # type: ignore from google.cloud.errorreporting_v1beta1.types import common -from google.protobuf import duration_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore __protobuf__ = proto.module( diff --git a/google/cloud/errorreporting_v1beta1/types/report_errors_service.py b/google/cloud/errorreporting_v1beta1/types/report_errors_service.py index 2a5072fb..68b23ecf 100644 --- a/google/cloud/errorreporting_v1beta1/types/report_errors_service.py +++ b/google/cloud/errorreporting_v1beta1/types/report_errors_service.py @@ -20,7 +20,7 @@ import proto # type: ignore from google.cloud.errorreporting_v1beta1.types import common -from google.protobuf import timestamp_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore __protobuf__ = proto.module( diff --git a/mypy.ini b/mypy.ini index 574c5aed..e0e0da2e 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,3 +1,15 @@ [mypy] -python_version = 3.7 +python_version = 3.14 namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/testing/constraints-3.10.txt b/testing/constraints-3.10.txt index 93e6826f..7599dea4 100644 --- a/testing/constraints-3.10.txt +++ b/testing/constraints-3.10.txt @@ -6,3 +6,5 @@ google-auth grpcio proto-plus protobuf +# cryptography is a direct dependency of google-auth +cryptography diff --git a/testing/constraints-3.11.txt b/testing/constraints-3.11.txt index 93e6826f..7599dea4 100644 --- a/testing/constraints-3.11.txt +++ b/testing/constraints-3.11.txt @@ -6,3 +6,5 @@ google-auth grpcio proto-plus protobuf +# cryptography is a direct dependency of google-auth +cryptography diff --git a/testing/constraints-3.12.txt b/testing/constraints-3.12.txt index 93e6826f..7599dea4 100644 --- a/testing/constraints-3.12.txt +++ b/testing/constraints-3.12.txt @@ -6,3 +6,5 @@ google-auth grpcio proto-plus protobuf +# cryptography is a direct dependency of google-auth +cryptography diff --git a/testing/constraints-3.9.txt b/testing/constraints-3.9.txt index 93e6826f..7599dea4 100644 --- a/testing/constraints-3.9.txt +++ b/testing/constraints-3.9.txt @@ -6,3 +6,5 @@ google-auth grpcio proto-plus protobuf +# cryptography is a direct dependency of google-auth +cryptography 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 c98fd691..10807479 100644 --- a/tests/unit/gapic/errorreporting_v1beta1/test_error_group_service.py +++ b/tests/unit/gapic/errorreporting_v1beta1/test_error_group_service.py @@ -29,6 +29,7 @@ import json import math import pytest +from collections.abc import Sequence, Mapping from google.api_core import api_core_version from proto.marshal.rules.dates import DurationRule, TimestampRule from proto.marshal.rules import wrappers 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 f47cbc80..386d0df3 100644 --- a/tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py +++ b/tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py @@ -29,6 +29,7 @@ import json import math import pytest +from collections.abc import Sequence, Mapping from google.api_core import api_core_version from proto.marshal.rules.dates import DurationRule, TimestampRule from proto.marshal.rules import wrappers @@ -64,9 +65,9 @@ from google.cloud.errorreporting_v1beta1.types import common from google.cloud.errorreporting_v1beta1.types import error_stats_service from google.oauth2 import service_account -from google.protobuf import duration_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore import google.auth +import google.protobuf.duration_pb2 as duration_pb2 # type: ignore +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore CRED_INFO_JSON = { 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 45def7bc..dd0d6be0 100644 --- a/tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py +++ b/tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py @@ -29,6 +29,7 @@ import json import math import pytest +from collections.abc import Sequence, Mapping from google.api_core import api_core_version from proto.marshal.rules.dates import DurationRule, TimestampRule from proto.marshal.rules import wrappers @@ -65,8 +66,8 @@ from google.cloud.errorreporting_v1beta1.types import common from google.cloud.errorreporting_v1beta1.types import report_errors_service from google.oauth2 import service_account -from google.protobuf import timestamp_pb2 # type: ignore import google.auth +import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore CRED_INFO_JSON = { From 7ac7f6b9038b01cc4b3e0c4ca63df981485dd6db Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Mon, 23 Feb 2026 14:32:39 -0500 Subject: [PATCH 11/11] build: update README to indicate that source has moved and delete all files (#728) Towards https://github.com/googleapis/google-cloud-python/issues/11029. --- .coveragerc | 13 - .flake8 | 34 - .github/CODEOWNERS | 12 - .github/CONTRIBUTING.md | 28 - .github/ISSUE_TEMPLATE/bug_report.md | 43 - .github/ISSUE_TEMPLATE/feature_request.md | 18 - .github/ISSUE_TEMPLATE/support_request.md | 7 - .github/PULL_REQUEST_TEMPLATE.md | 7 - .github/auto-label.yaml | 19 - .github/blunderbuss.yml | 17 - .github/flakybot.yaml | 15 - .github/header-checker-lint.yml | 15 - .github/release-trigger.yml | 2 - .github/snippet-bot.yml | 0 .github/workflows/docs.yml | 38 - .github/workflows/lint.yml | 25 - .github/workflows/unittest.yml | 61 - .gitignore | 64 - .kokoro/build.sh | 60 - .kokoro/common_env_vars.cfg | 19 - .kokoro/continuous/common.cfg | 47 - .kokoro/continuous/continuous.cfg | 1 - .kokoro/continuous/prerelease-deps.cfg | 7 - .kokoro/populate-secrets.sh | 43 - .kokoro/presubmit/common.cfg | 47 - .kokoro/presubmit/prerelease-deps.cfg | 7 - .kokoro/presubmit/presubmit.cfg | 1 - .kokoro/samples/lint/common.cfg | 53 - .kokoro/samples/lint/continuous.cfg | 6 - .kokoro/samples/lint/periodic.cfg | 6 - .kokoro/samples/lint/presubmit.cfg | 6 - .kokoro/samples/python3.10/common.cfg | 59 - .kokoro/samples/python3.10/continuous.cfg | 6 - .kokoro/samples/python3.10/periodic-head.cfg | 11 - .kokoro/samples/python3.10/periodic.cfg | 6 - .kokoro/samples/python3.10/presubmit.cfg | 6 - .kokoro/samples/python3.11/common.cfg | 59 - .kokoro/samples/python3.11/continuous.cfg | 6 - .kokoro/samples/python3.11/periodic-head.cfg | 11 - .kokoro/samples/python3.11/periodic.cfg | 6 - .kokoro/samples/python3.11/presubmit.cfg | 6 - .kokoro/samples/python3.12/common.cfg | 59 - .kokoro/samples/python3.12/continuous.cfg | 6 - .kokoro/samples/python3.12/periodic-head.cfg | 11 - .kokoro/samples/python3.12/periodic.cfg | 6 - .kokoro/samples/python3.12/presubmit.cfg | 6 - .kokoro/samples/python3.13/common.cfg | 60 - .kokoro/samples/python3.13/continuous.cfg | 6 - .kokoro/samples/python3.13/periodic-head.cfg | 11 - .kokoro/samples/python3.13/periodic.cfg | 6 - .kokoro/samples/python3.13/presubmit.cfg | 6 - .kokoro/samples/python3.14/common.cfg | 60 - .kokoro/samples/python3.14/continuous.cfg | 6 - .kokoro/samples/python3.14/periodic-head.cfg | 11 - .kokoro/samples/python3.14/periodic.cfg | 6 - .kokoro/samples/python3.14/presubmit.cfg | 6 - .kokoro/samples/python3.7/common.cfg | 59 - .kokoro/samples/python3.7/continuous.cfg | 6 - .kokoro/samples/python3.7/periodic-head.cfg | 11 - .kokoro/samples/python3.7/periodic.cfg | 6 - .kokoro/samples/python3.7/presubmit.cfg | 6 - .kokoro/samples/python3.8/common.cfg | 59 - .kokoro/samples/python3.8/continuous.cfg | 6 - .kokoro/samples/python3.8/periodic-head.cfg | 11 - .kokoro/samples/python3.8/periodic.cfg | 6 - .kokoro/samples/python3.8/presubmit.cfg | 6 - .kokoro/samples/python3.9/common.cfg | 59 - .kokoro/samples/python3.9/continuous.cfg | 6 - .kokoro/samples/python3.9/periodic-head.cfg | 11 - .kokoro/samples/python3.9/periodic.cfg | 6 - .kokoro/samples/python3.9/presubmit.cfg | 6 - .kokoro/test-samples-against-head.sh | 26 - .kokoro/test-samples-impl.sh | 103 - .kokoro/test-samples.sh | 44 - .kokoro/trampoline.sh | 28 - .kokoro/trampoline_v2.sh | 487 -- .../generator-input/.repo-metadata.json | 18 - .librarian/generator-input/librarian.py | 76 - .librarian/generator-input/noxfile.py | 487 -- .librarian/generator-input/setup.py | 99 - .librarian/state.yaml | 42 - .pre-commit-config.yaml | 31 - .trampolinerc | 61 - CHANGELOG.md | 519 -- CODE_OF_CONDUCT.md | 95 - CONTRIBUTING.rst | 287 - MANIFEST.in | 20 - README.rst | 5 + ...ools-clouderrorreporting-v1beta1-py.tar.gz | 0 docs/README.rst | 197 - docs/_static/custom.css | 20 - docs/_templates/layout.html | 50 - docs/changelog.md | 1 - docs/client.rst | 6 - docs/conf.py | 418 -- .../error_group_service.rst | 6 - .../error_stats_service.rst | 10 - .../report_errors_service.rst | 6 - docs/errorreporting_v1beta1/services_.rst | 8 - docs/errorreporting_v1beta1/types_.rst | 6 - docs/index.rst | 39 - docs/multiprocessing.rst | 7 - docs/summary_overview.md | 22 - docs/usage.rst | 115 - docs/util.rst | 6 - google/cloud/error_reporting/__init__.py | 26 - google/cloud/error_reporting/_gapic.py | 77 - google/cloud/error_reporting/_logging.py | 91 - google/cloud/error_reporting/client.py | 387 -- google/cloud/error_reporting/gapic_version.py | 16 - google/cloud/error_reporting/util.py | 47 - .../cloud/errorreporting_v1beta1/__init__.py | 190 - .../gapic_metadata.json | 156 - .../errorreporting_v1beta1/gapic_version.py | 16 - google/cloud/errorreporting_v1beta1/py.typed | 2 - .../services/__init__.py | 15 - .../services/error_group_service/__init__.py | 22 - .../error_group_service/async_client.py | 561 -- .../services/error_group_service/client.py | 989 ---- .../error_group_service/transports/README.rst | 9 - .../transports/__init__.py | 38 - .../error_group_service/transports/base.py | 185 - .../error_group_service/transports/grpc.py | 387 -- .../transports/grpc_asyncio.py | 417 -- .../error_group_service/transports/rest.py | 608 -- .../transports/rest_base.py | 207 - .../services/error_stats_service/__init__.py | 22 - .../error_stats_service/async_client.py | 767 --- .../services/error_stats_service/client.py | 1192 ---- .../services/error_stats_service/pagers.py | 353 -- .../error_stats_service/transports/README.rst | 9 - .../transports/__init__.py | 38 - .../error_stats_service/transports/base.py | 207 - .../error_stats_service/transports/grpc.py | 420 -- .../transports/grpc_asyncio.py | 454 -- .../error_stats_service/transports/rest.py | 841 --- .../transports/rest_base.py | 248 - .../report_errors_service/__init__.py | 22 - .../report_errors_service/async_client.py | 467 -- .../services/report_errors_service/client.py | 885 --- .../transports/README.rst | 9 - .../transports/__init__.py | 40 - .../report_errors_service/transports/base.py | 173 - .../report_errors_service/transports/grpc.py | 383 -- .../transports/grpc_asyncio.py | 406 -- .../report_errors_service/transports/rest.py | 413 -- .../transports/rest_base.py | 150 - .../errorreporting_v1beta1/types/__init__.py | 76 - .../errorreporting_v1beta1/types/common.py | 366 -- .../types/error_group_service.py | 83 - .../types/error_stats_service.py | 634 --- .../types/report_errors_service.py | 137 - librarian.py | 76 - mypy.ini | 15 - noxfile.py | 491 -- pylint.config.py | 25 - pytest.ini | 28 - renovate.json | 12 - samples/AUTHORING_GUIDE.md | 1 - samples/CONTRIBUTING.md | 1 - ...ted_error_group_service_get_group_async.py | 52 - ...ated_error_group_service_get_group_sync.py | 52 - ..._error_group_service_update_group_async.py | 51 - ...d_error_group_service_update_group_sync.py | 51 - ...error_stats_service_delete_events_async.py | 52 - ..._error_stats_service_delete_events_sync.py | 52 - ...d_error_stats_service_list_events_async.py | 54 - ...ed_error_stats_service_list_events_sync.py | 54 - ...or_stats_service_list_group_stats_async.py | 53 - ...ror_stats_service_list_group_stats_sync.py | 53 - ...errors_service_report_error_event_async.py | 56 - ..._errors_service_report_error_event_sync.py | 56 - ....devtools.clouderrorreporting.v1beta1.json | 1005 ---- samples/snippets/README.md | 4 - scripts/decrypt-secrets.sh | 46 - scripts/readme-gen/readme_gen.py | 69 - scripts/readme-gen/templates/README.tmpl.rst | 87 - scripts/readme-gen/templates/auth.tmpl.rst | 9 - .../templates/auth_api_key.tmpl.rst | 14 - .../templates/install_deps.tmpl.rst | 29 - .../templates/install_portaudio.tmpl.rst | 35 - setup.py | 103 - testing/.gitignore | 3 - testing/constraints-3.10.txt | 10 - testing/constraints-3.11.txt | 10 - testing/constraints-3.12.txt | 10 - testing/constraints-3.13.txt | 12 - testing/constraints-3.14.txt | 12 - testing/constraints-3.7.txt | 11 - testing/constraints-3.8.txt | 6 - testing/constraints-3.9.txt | 10 - tests/__init__.py | 15 - ...st_system_report_errors_service_v1beta1.py | 48 - tests/system/test_system.py | 136 - tests/unit/__init__.py | 15 - tests/unit/gapic/__init__.py | 15 - .../gapic/errorreporting_v1beta1/__init__.py | 15 - .../test_error_group_service.py | 3625 ------------ .../test_error_stats_service.py | 4887 ----------------- .../test_report_errors_service.py | 3001 ---------- tests/unit/test__gapic.py | 81 - tests/unit/test__logging.py | 86 - tests/unit/test_client.py | 221 - tests/unit/test_packaging.py | 57 - tests/unit/test_util.py | 46 - 205 files changed, 5 insertions(+), 33026 deletions(-) delete mode 100644 .coveragerc delete mode 100644 .flake8 delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/CONTRIBUTING.md delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 .github/ISSUE_TEMPLATE/support_request.md delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md delete mode 100644 .github/auto-label.yaml delete mode 100644 .github/blunderbuss.yml delete mode 100644 .github/flakybot.yaml delete mode 100644 .github/header-checker-lint.yml delete mode 100644 .github/release-trigger.yml delete mode 100644 .github/snippet-bot.yml delete mode 100644 .github/workflows/docs.yml delete mode 100644 .github/workflows/lint.yml delete mode 100644 .github/workflows/unittest.yml delete mode 100644 .gitignore delete mode 100755 .kokoro/build.sh delete mode 100644 .kokoro/common_env_vars.cfg delete mode 100644 .kokoro/continuous/common.cfg delete mode 100644 .kokoro/continuous/continuous.cfg delete mode 100644 .kokoro/continuous/prerelease-deps.cfg delete mode 100755 .kokoro/populate-secrets.sh delete mode 100644 .kokoro/presubmit/common.cfg delete mode 100644 .kokoro/presubmit/prerelease-deps.cfg delete mode 100644 .kokoro/presubmit/presubmit.cfg delete mode 100644 .kokoro/samples/lint/common.cfg delete mode 100644 .kokoro/samples/lint/continuous.cfg delete mode 100644 .kokoro/samples/lint/periodic.cfg delete mode 100644 .kokoro/samples/lint/presubmit.cfg delete mode 100644 .kokoro/samples/python3.10/common.cfg delete mode 100644 .kokoro/samples/python3.10/continuous.cfg delete mode 100644 .kokoro/samples/python3.10/periodic-head.cfg delete mode 100644 .kokoro/samples/python3.10/periodic.cfg delete mode 100644 .kokoro/samples/python3.10/presubmit.cfg delete mode 100644 .kokoro/samples/python3.11/common.cfg delete mode 100644 .kokoro/samples/python3.11/continuous.cfg delete mode 100644 .kokoro/samples/python3.11/periodic-head.cfg delete mode 100644 .kokoro/samples/python3.11/periodic.cfg delete mode 100644 .kokoro/samples/python3.11/presubmit.cfg delete mode 100644 .kokoro/samples/python3.12/common.cfg delete mode 100644 .kokoro/samples/python3.12/continuous.cfg delete mode 100644 .kokoro/samples/python3.12/periodic-head.cfg delete mode 100644 .kokoro/samples/python3.12/periodic.cfg delete mode 100644 .kokoro/samples/python3.12/presubmit.cfg delete mode 100644 .kokoro/samples/python3.13/common.cfg delete mode 100644 .kokoro/samples/python3.13/continuous.cfg delete mode 100644 .kokoro/samples/python3.13/periodic-head.cfg delete mode 100644 .kokoro/samples/python3.13/periodic.cfg delete mode 100644 .kokoro/samples/python3.13/presubmit.cfg delete mode 100644 .kokoro/samples/python3.14/common.cfg delete mode 100644 .kokoro/samples/python3.14/continuous.cfg delete mode 100644 .kokoro/samples/python3.14/periodic-head.cfg delete mode 100644 .kokoro/samples/python3.14/periodic.cfg delete mode 100644 .kokoro/samples/python3.14/presubmit.cfg delete mode 100644 .kokoro/samples/python3.7/common.cfg delete mode 100644 .kokoro/samples/python3.7/continuous.cfg delete mode 100644 .kokoro/samples/python3.7/periodic-head.cfg delete mode 100644 .kokoro/samples/python3.7/periodic.cfg delete mode 100644 .kokoro/samples/python3.7/presubmit.cfg delete mode 100644 .kokoro/samples/python3.8/common.cfg delete mode 100644 .kokoro/samples/python3.8/continuous.cfg delete mode 100644 .kokoro/samples/python3.8/periodic-head.cfg delete mode 100644 .kokoro/samples/python3.8/periodic.cfg delete mode 100644 .kokoro/samples/python3.8/presubmit.cfg delete mode 100644 .kokoro/samples/python3.9/common.cfg delete mode 100644 .kokoro/samples/python3.9/continuous.cfg delete mode 100644 .kokoro/samples/python3.9/periodic-head.cfg delete mode 100644 .kokoro/samples/python3.9/periodic.cfg delete mode 100644 .kokoro/samples/python3.9/presubmit.cfg delete mode 100755 .kokoro/test-samples-against-head.sh delete mode 100755 .kokoro/test-samples-impl.sh delete mode 100755 .kokoro/test-samples.sh delete mode 100755 .kokoro/trampoline.sh delete mode 100755 .kokoro/trampoline_v2.sh delete mode 100644 .librarian/generator-input/.repo-metadata.json delete mode 100644 .librarian/generator-input/librarian.py delete mode 100644 .librarian/generator-input/noxfile.py delete mode 100644 .librarian/generator-input/setup.py delete mode 100644 .librarian/state.yaml delete mode 100644 .pre-commit-config.yaml delete mode 100644 .trampolinerc delete mode 100644 CHANGELOG.md delete mode 100644 CODE_OF_CONDUCT.md delete mode 100644 CONTRIBUTING.rst delete mode 100644 MANIFEST.in delete mode 100644 devtools-clouderrorreporting-v1beta1-py.tar.gz delete mode 100644 docs/README.rst delete mode 100644 docs/_static/custom.css delete mode 100644 docs/_templates/layout.html delete mode 120000 docs/changelog.md delete mode 100644 docs/client.rst delete mode 100644 docs/conf.py delete mode 100644 docs/errorreporting_v1beta1/error_group_service.rst delete mode 100644 docs/errorreporting_v1beta1/error_stats_service.rst delete mode 100644 docs/errorreporting_v1beta1/report_errors_service.rst delete mode 100644 docs/errorreporting_v1beta1/services_.rst delete mode 100644 docs/errorreporting_v1beta1/types_.rst delete mode 100644 docs/index.rst delete mode 100644 docs/multiprocessing.rst delete mode 100644 docs/summary_overview.md delete mode 100644 docs/usage.rst delete mode 100644 docs/util.rst delete mode 100644 google/cloud/error_reporting/__init__.py delete mode 100644 google/cloud/error_reporting/_gapic.py delete mode 100644 google/cloud/error_reporting/_logging.py delete mode 100644 google/cloud/error_reporting/client.py delete mode 100644 google/cloud/error_reporting/gapic_version.py delete mode 100644 google/cloud/error_reporting/util.py delete mode 100644 google/cloud/errorreporting_v1beta1/__init__.py delete mode 100644 google/cloud/errorreporting_v1beta1/gapic_metadata.json delete mode 100644 google/cloud/errorreporting_v1beta1/gapic_version.py delete mode 100644 google/cloud/errorreporting_v1beta1/py.typed delete mode 100644 google/cloud/errorreporting_v1beta1/services/__init__.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_group_service/__init__.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_group_service/async_client.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_group_service/client.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_group_service/transports/README.rst delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_group_service/transports/__init__.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_group_service/transports/base.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc_asyncio.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_group_service/transports/rest.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_group_service/transports/rest_base.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_stats_service/__init__.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_stats_service/async_client.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_stats_service/client.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_stats_service/pagers.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/README.rst delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/__init__.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/base.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc_asyncio.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/rest.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/rest_base.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/report_errors_service/__init__.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/report_errors_service/async_client.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/README.rst delete mode 100644 google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/__init__.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/base.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc_asyncio.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/rest.py delete mode 100644 google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/rest_base.py delete mode 100644 google/cloud/errorreporting_v1beta1/types/__init__.py delete mode 100644 google/cloud/errorreporting_v1beta1/types/common.py delete mode 100644 google/cloud/errorreporting_v1beta1/types/error_group_service.py delete mode 100644 google/cloud/errorreporting_v1beta1/types/error_stats_service.py delete mode 100644 google/cloud/errorreporting_v1beta1/types/report_errors_service.py delete mode 100644 librarian.py delete mode 100644 mypy.ini delete mode 100644 noxfile.py delete mode 100644 pylint.config.py delete mode 100644 pytest.ini delete mode 100644 renovate.json delete mode 100644 samples/AUTHORING_GUIDE.md delete mode 100644 samples/CONTRIBUTING.md delete mode 100644 samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_get_group_async.py delete mode 100644 samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_get_group_sync.py delete mode 100644 samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_update_group_async.py delete mode 100644 samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_update_group_sync.py delete mode 100644 samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_delete_events_async.py delete mode 100644 samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_delete_events_sync.py delete mode 100644 samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_events_async.py delete mode 100644 samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_events_sync.py delete mode 100644 samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_group_stats_async.py delete mode 100644 samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_group_stats_sync.py delete mode 100644 samples/generated_samples/clouderrorreporting_v1beta1_generated_report_errors_service_report_error_event_async.py delete mode 100644 samples/generated_samples/clouderrorreporting_v1beta1_generated_report_errors_service_report_error_event_sync.py delete mode 100644 samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json delete mode 100644 samples/snippets/README.md delete mode 100755 scripts/decrypt-secrets.sh delete mode 100644 scripts/readme-gen/readme_gen.py delete mode 100644 scripts/readme-gen/templates/README.tmpl.rst delete mode 100644 scripts/readme-gen/templates/auth.tmpl.rst delete mode 100644 scripts/readme-gen/templates/auth_api_key.tmpl.rst delete mode 100644 scripts/readme-gen/templates/install_deps.tmpl.rst delete mode 100644 scripts/readme-gen/templates/install_portaudio.tmpl.rst delete mode 100644 setup.py delete mode 100644 testing/.gitignore delete mode 100644 testing/constraints-3.10.txt delete mode 100644 testing/constraints-3.11.txt delete mode 100644 testing/constraints-3.12.txt delete mode 100644 testing/constraints-3.13.txt delete mode 100644 testing/constraints-3.14.txt delete mode 100644 testing/constraints-3.7.txt delete mode 100644 testing/constraints-3.8.txt delete mode 100644 testing/constraints-3.9.txt delete mode 100644 tests/__init__.py delete mode 100644 tests/system/gapic/v1beta1/test_system_report_errors_service_v1beta1.py delete mode 100644 tests/system/test_system.py delete mode 100644 tests/unit/__init__.py delete mode 100644 tests/unit/gapic/__init__.py delete mode 100644 tests/unit/gapic/errorreporting_v1beta1/__init__.py delete mode 100644 tests/unit/gapic/errorreporting_v1beta1/test_error_group_service.py delete mode 100644 tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py delete mode 100644 tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py delete mode 100644 tests/unit/test__gapic.py delete mode 100644 tests/unit/test__logging.py delete mode 100644 tests/unit/test_client.py delete mode 100644 tests/unit/test_packaging.py delete mode 100644 tests/unit/test_util.py diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 9aac2710..00000000 --- a/.coveragerc +++ /dev/null @@ -1,13 +0,0 @@ -[run] -branch = True - -[report] -show_missing = True -omit = - google/cloud/errorreporting/__init__.py - google/cloud/errorreporting/gapic_version.py -exclude_lines = - # Re-enable the standard pragma - pragma: NO COVER - # Ignore debug-only repr - def __repr__ diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 90316de2..00000000 --- a/.flake8 +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -[flake8] -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): -# Resolve flake8 lint issues -ignore = E203, E231, E266, E501, W503 -exclude = - # TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): - # Ensure that generated code passes flake8 lint - **/gapic/** - **/services/** - **/types/** - # Exclude Protobuf gencode - *_pb2.py - - # Standard linting exemptions. - **/.nox/** - __pycache__, - .git, - *.pyc, - conf.py diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index b3aefa82..00000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,12 +0,0 @@ -# Code owners file. -# This file controls who is tagged for review for any given pull request. -# -# For syntax help see: -# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax -# Note: This file is autogenerated. To make changes to the codeowner team, please update .repo-metadata.json. - -# @googleapis/yoshi-python are the default owners for changes in this repo -* @googleapis/yoshi-python - -# @googleapis/python-samples-reviewers are the default owners for samples changes -/samples/ @googleapis/python-samples-reviewers diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md deleted file mode 100644 index 939e5341..00000000 --- a/.github/CONTRIBUTING.md +++ /dev/null @@ -1,28 +0,0 @@ -# How to Contribute - -We'd love to accept your patches and contributions to this project. There are -just a few small guidelines you need to follow. - -## Contributor License Agreement - -Contributions to this project must be accompanied by a Contributor License -Agreement. You (or your employer) retain the copyright to your contribution; -this simply gives us permission to use and redistribute your contributions as -part of the project. Head over to to see -your current agreements on file or to sign a new one. - -You generally only need to submit a CLA once, so if you've already submitted one -(even if it was for a different project), you probably don't need to do it -again. - -## Code reviews - -All submissions, including submissions by project members, require review. We -use GitHub pull requests for this purpose. Consult -[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more -information on using pull requests. - -## Community Guidelines - -This project follows [Google's Open Source Community -Guidelines](https://opensource.google.com/conduct/). diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index fcbad57e..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve - ---- - -Thanks for stopping by to let us know something could be better! - -**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. - -Please run down the following list and make sure you've tried the usual "quick fixes": - - - Search the issues already opened: https://github.com/googleapis/python-error-reporting/issues - - Search StackOverflow: https://stackoverflow.com/questions/tagged/google-cloud-platform+python - -If you are still having issues, please be sure to include as much information as possible: - -#### Environment details - - - OS type and version: - - Python version: `python --version` - - pip version: `pip --version` - - `google-cloud-error-reporting` version: `pip show google-cloud-error-reporting` - -#### Steps to reproduce - - 1. ? - 2. ? - -#### Code example - -```python -# example -``` - -#### Stack trace -``` -# example -``` - -Making sure to follow these steps will guarantee the quickest resolution possible. - -Thanks! diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 6365857f..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this library - ---- - -Thanks for stopping by to let us know something could be better! - -**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. - - **Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - **Describe the solution you'd like** -A clear and concise description of what you want to happen. - **Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - **Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/support_request.md b/.github/ISSUE_TEMPLATE/support_request.md deleted file mode 100644 index 99586903..00000000 --- a/.github/ISSUE_TEMPLATE/support_request.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: Support request -about: If you have a support contract with Google, please create an issue in the Google Cloud Support console. - ---- - -**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 5884ea52..00000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,7 +0,0 @@ -Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: -- [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/python-error-reporting/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea -- [ ] Ensure the tests and linter pass -- [ ] Code coverage does not decrease (if any source code was changed) -- [ ] Appropriate docs were updated (if necessary) - -Fixes # 🦕 diff --git a/.github/auto-label.yaml b/.github/auto-label.yaml deleted file mode 100644 index ccad49b4..00000000 --- a/.github/auto-label.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -requestsize: - enabled: true -staleness: - pullrequest: true - old: 30 - extraold: 60 diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml deleted file mode 100644 index dec2056f..00000000 --- a/.github/blunderbuss.yml +++ /dev/null @@ -1,17 +0,0 @@ -# Blunderbuss config -# -# This file controls who is assigned for pull requests and issues. -# Note: This file is autogenerated. To make changes to the assignee -# team, please update `codeowner_team` in `.repo-metadata.json`. -assign_issues: - - googleapis/yoshi-python - -assign_issues_by: - - labels: - - "samples" - to: - - googleapis/python-samples-reviewers - - googleapis/yoshi-python - -assign_prs: - - googleapis/yoshi-python diff --git a/.github/flakybot.yaml b/.github/flakybot.yaml deleted file mode 100644 index 2159a1bc..00000000 --- a/.github/flakybot.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -issuePriority: p2 \ No newline at end of file diff --git a/.github/header-checker-lint.yml b/.github/header-checker-lint.yml deleted file mode 100644 index 6fe78aa7..00000000 --- a/.github/header-checker-lint.yml +++ /dev/null @@ -1,15 +0,0 @@ -{"allowedCopyrightHolders": ["Google LLC"], - "allowedLicenses": ["Apache-2.0", "MIT", "BSD-3"], - "ignoreFiles": ["**/requirements.txt", "**/requirements-test.txt", "**/__init__.py", "samples/**/constraints.txt", "samples/**/constraints-test.txt"], - "sourceFileExtensions": [ - "ts", - "js", - "java", - "sh", - "Dockerfile", - "yaml", - "py", - "html", - "txt" - ] -} \ No newline at end of file diff --git a/.github/release-trigger.yml b/.github/release-trigger.yml deleted file mode 100644 index c1b20096..00000000 --- a/.github/release-trigger.yml +++ /dev/null @@ -1,2 +0,0 @@ -enabled: true -multiScmName: python-error-reporting diff --git a/.github/snippet-bot.yml b/.github/snippet-bot.yml deleted file mode 100644 index e69de29b..00000000 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index c5ee9883..00000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,38 +0,0 @@ -on: - pull_request: - branches: - - main -name: docs -jobs: - docs: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Setup Python - uses: actions/setup-python@v6 - with: - python-version: "3.10" - - name: Install nox - run: | - python -m pip install --upgrade setuptools pip wheel - python -m pip install nox - - name: Run docs - run: | - nox -s docs - docfx: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Setup Python - uses: actions/setup-python@v6 - with: - python-version: "3.10" - - name: Install nox - run: | - python -m pip install --upgrade setuptools pip wheel - python -m pip install nox - - name: Run docfx - run: | - nox -s docfx diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index a5293348..00000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,25 +0,0 @@ -on: - pull_request: - branches: - - main -name: lint -jobs: - lint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Setup Python - uses: actions/setup-python@v6 - with: - python-version: "3.14" - - name: Install nox - run: | - python -m pip install --upgrade setuptools pip wheel - python -m pip install nox - - name: Run lint - run: | - nox -s lint - - name: Run lint_setup_py - run: | - nox -s lint_setup_py diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml deleted file mode 100644 index cc6fe2b2..00000000 --- a/.github/workflows/unittest.yml +++ /dev/null @@ -1,61 +0,0 @@ -on: - pull_request: - branches: - - main -name: unittest -jobs: - unit: - # TODO(https://github.com/googleapis/gapic-generator-python/issues/2303): use `ubuntu-latest` once this bug is fixed. - # Use ubuntu-22.04 until Python 3.7 is removed from the test matrix - # https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories - runs-on: ubuntu-22.04 - strategy: - matrix: - python: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} - - name: Install nox - run: | - python -m pip install --upgrade setuptools pip wheel - python -m pip install nox - - name: Run unit tests - env: - COVERAGE_FILE: .coverage-${{ matrix.python }} - run: | - nox -s unit-${{ matrix.python }} - - name: Upload coverage results - uses: actions/upload-artifact@v4 - with: - name: coverage-artifact-${{ matrix.python }} - path: .coverage-${{ matrix.python }} - include-hidden-files: true - - cover: - runs-on: ubuntu-latest - needs: - - unit - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: "3.14" - - name: Install coverage - run: | - python -m pip install --upgrade setuptools pip wheel - python -m pip install coverage - - name: Download coverage results - uses: actions/download-artifact@v4 - with: - path: .coverage-results/ - - name: Report coverage results - run: | - find .coverage-results -type f -name '*.zip' -exec unzip {} \; - coverage combine .coverage-results/**/.coverage* - coverage report --show-missing --fail-under=100 diff --git a/.gitignore b/.gitignore deleted file mode 100644 index d083ea1d..00000000 --- a/.gitignore +++ /dev/null @@ -1,64 +0,0 @@ -*.py[cod] -*.sw[op] - -# C extensions -*.so - -# Packages -*.egg -*.egg-info -dist -build -eggs -.eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg -lib -lib64 -__pycache__ - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage -.nox -.cache -.pytest_cache - - -# Mac -.DS_Store - -# JetBrains -.idea - -# VS Code -.vscode - -# emacs -*~ - -# Built documentation -docs/_build -bigquery/docs/generated -docs.metadata - -# Virtual environment -env/ -venv/ - -# Test logs -coverage.xml -*sponge_log.xml - -# System test environment variables. -system_tests/local_test_setup - -# Make sure a generated file isn't accidentally committed. -pylintrc -pylintrc.test diff --git a/.kokoro/build.sh b/.kokoro/build.sh deleted file mode 100755 index d41b45aa..00000000 --- a/.kokoro/build.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.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. - -set -eo pipefail - -CURRENT_DIR=$(dirname "${BASH_SOURCE[0]}") - -if [[ -z "${PROJECT_ROOT:-}" ]]; then - PROJECT_ROOT=$(realpath "${CURRENT_DIR}/..") -fi - -pushd "${PROJECT_ROOT}" - -# Disable buffering, so that the logs stream through. -export PYTHONUNBUFFERED=1 - -# Debug: show build environment -env | grep KOKORO - -# Setup service account credentials. -if [[ -f "${KOKORO_GFILE_DIR}/service-account.json" ]] -then - export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json -fi - -# Setup project id. -if [[ -f "${KOKORO_GFILE_DIR}/project-id.json" ]] -then - export PROJECT_ID=$(cat "${KOKORO_GFILE_DIR}/project-id.json") -fi - -# If this is a continuous build, send the test log to the FlakyBot. -# See https://github.com/googleapis/repo-automation-bots/tree/main/packages/flakybot. -if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]]; then - cleanup() { - chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot - $KOKORO_GFILE_DIR/linux_amd64/flakybot - } - trap cleanup EXIT HUP -fi - -# If NOX_SESSION is set, it only runs the specified session, -# otherwise run all the sessions. -if [[ -n "${NOX_SESSION:-}" ]]; then - python3 -m nox -s ${NOX_SESSION:-} -else - python3 -m nox -fi diff --git a/.kokoro/common_env_vars.cfg b/.kokoro/common_env_vars.cfg deleted file mode 100644 index b5c22b80..00000000 --- a/.kokoro/common_env_vars.cfg +++ /dev/null @@ -1,19 +0,0 @@ - -############################################# -# this section merged from .kokoro/common_env_vars.cfg using owlbot.py - -env_vars: { - key: "PRODUCT_AREA_LABEL" - value: "observability" -} -env_vars: { - key: "PRODUCT_LABEL" - value: "error-reporting" -} -env_vars: { - key: "LANGUAGE_LABEL" - value: "python" -} - -################################################### - diff --git a/.kokoro/continuous/common.cfg b/.kokoro/continuous/common.cfg deleted file mode 100644 index c337b6d8..00000000 --- a/.kokoro/continuous/common.cfg +++ /dev/null @@ -1,47 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Download resources for system tests (service account key, etc.) -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-python" - -# Use the trampoline script to run in docker. -build_file: "python-error-reporting/.kokoro/trampoline.sh" - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-multi" -} -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-error-reporting/.kokoro/build.sh" -} - - -############################################# -# this section merged from .kokoro/common_env_vars.cfg using owlbot.py - -env_vars: { - key: "PRODUCT_AREA_LABEL" - value: "observability" -} -env_vars: { - key: "PRODUCT_LABEL" - value: "error-reporting" -} -env_vars: { - key: "LANGUAGE_LABEL" - value: "python" -} - -################################################### - diff --git a/.kokoro/continuous/continuous.cfg b/.kokoro/continuous/continuous.cfg deleted file mode 100644 index 8f43917d..00000000 --- a/.kokoro/continuous/continuous.cfg +++ /dev/null @@ -1 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto \ No newline at end of file diff --git a/.kokoro/continuous/prerelease-deps.cfg b/.kokoro/continuous/prerelease-deps.cfg deleted file mode 100644 index 3595fb43..00000000 --- a/.kokoro/continuous/prerelease-deps.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Only run this nox session. -env_vars: { - key: "NOX_SESSION" - value: "prerelease_deps" -} diff --git a/.kokoro/populate-secrets.sh b/.kokoro/populate-secrets.sh deleted file mode 100755 index c435402f..00000000 --- a/.kokoro/populate-secrets.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -# Copyright 2024 Google LLC. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -eo pipefail - -function now { date +"%Y-%m-%d %H:%M:%S" | tr -d '\n' ;} -function msg { println "$*" >&2 ;} -function println { printf '%s\n' "$(now) $*" ;} - - -# Populates requested secrets set in SECRET_MANAGER_KEYS from service account: -# kokoro-trampoline@cloud-devrel-kokoro-resources.iam.gserviceaccount.com -SECRET_LOCATION="${KOKORO_GFILE_DIR}/secret_manager" -msg "Creating folder on disk for secrets: ${SECRET_LOCATION}" -mkdir -p ${SECRET_LOCATION} -for key in $(echo ${SECRET_MANAGER_KEYS} | sed "s/,/ /g") -do - msg "Retrieving secret ${key}" - docker run --entrypoint=gcloud \ - --volume=${KOKORO_GFILE_DIR}:${KOKORO_GFILE_DIR} \ - gcr.io/google.com/cloudsdktool/cloud-sdk \ - secrets versions access latest \ - --project cloud-devrel-kokoro-resources \ - --secret ${key} > \ - "${SECRET_LOCATION}/${key}" - if [[ $? == 0 ]]; then - msg "Secret written to ${SECRET_LOCATION}/${key}" - else - msg "Error retrieving secret ${key}" - fi -done diff --git a/.kokoro/presubmit/common.cfg b/.kokoro/presubmit/common.cfg deleted file mode 100644 index c337b6d8..00000000 --- a/.kokoro/presubmit/common.cfg +++ /dev/null @@ -1,47 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Download resources for system tests (service account key, etc.) -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-python" - -# Use the trampoline script to run in docker. -build_file: "python-error-reporting/.kokoro/trampoline.sh" - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-multi" -} -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-error-reporting/.kokoro/build.sh" -} - - -############################################# -# this section merged from .kokoro/common_env_vars.cfg using owlbot.py - -env_vars: { - key: "PRODUCT_AREA_LABEL" - value: "observability" -} -env_vars: { - key: "PRODUCT_LABEL" - value: "error-reporting" -} -env_vars: { - key: "LANGUAGE_LABEL" - value: "python" -} - -################################################### - diff --git a/.kokoro/presubmit/prerelease-deps.cfg b/.kokoro/presubmit/prerelease-deps.cfg deleted file mode 100644 index 3595fb43..00000000 --- a/.kokoro/presubmit/prerelease-deps.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Only run this nox session. -env_vars: { - key: "NOX_SESSION" - value: "prerelease_deps" -} diff --git a/.kokoro/presubmit/presubmit.cfg b/.kokoro/presubmit/presubmit.cfg deleted file mode 100644 index 8f43917d..00000000 --- a/.kokoro/presubmit/presubmit.cfg +++ /dev/null @@ -1 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto \ No newline at end of file diff --git a/.kokoro/samples/lint/common.cfg b/.kokoro/samples/lint/common.cfg deleted file mode 100644 index 3f98b562..00000000 --- a/.kokoro/samples/lint/common.cfg +++ /dev/null @@ -1,53 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Specify which tests to run -env_vars: { - key: "RUN_TESTS_SESSION" - value: "lint" -} - -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-error-reporting/.kokoro/test-samples.sh" -} - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" -} - -# Download secrets for samples -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Use the trampoline script to run in docker. -build_file: "python-error-reporting/.kokoro/trampoline_v2.sh" - -############################################# -# this section merged from .kokoro/common_env_vars.cfg using owlbot.py - -env_vars: { - key: "PRODUCT_AREA_LABEL" - value: "observability" -} -env_vars: { - key: "PRODUCT_LABEL" - value: "error-reporting" -} -env_vars: { - key: "LANGUAGE_LABEL" - value: "python" -} - -################################################### - diff --git a/.kokoro/samples/lint/continuous.cfg b/.kokoro/samples/lint/continuous.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/lint/continuous.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/lint/periodic.cfg b/.kokoro/samples/lint/periodic.cfg deleted file mode 100644 index 50fec964..00000000 --- a/.kokoro/samples/lint/periodic.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "False" -} \ No newline at end of file diff --git a/.kokoro/samples/lint/presubmit.cfg b/.kokoro/samples/lint/presubmit.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/lint/presubmit.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.10/common.cfg b/.kokoro/samples/python3.10/common.cfg deleted file mode 100644 index d19172ae..00000000 --- a/.kokoro/samples/python3.10/common.cfg +++ /dev/null @@ -1,59 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Specify which tests to run -env_vars: { - key: "RUN_TESTS_SESSION" - value: "py-3.10" -} - -# Declare build specific Cloud project. -env_vars: { - key: "BUILD_SPECIFIC_GCLOUD_PROJECT" - value: "python-docs-samples-tests-310" -} - -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-error-reporting/.kokoro/test-samples.sh" -} - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" -} - -# Download secrets for samples -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Use the trampoline script to run in docker. -build_file: "python-error-reporting/.kokoro/trampoline_v2.sh" - -############################################# -# this section merged from .kokoro/common_env_vars.cfg using owlbot.py - -env_vars: { - key: "PRODUCT_AREA_LABEL" - value: "observability" -} -env_vars: { - key: "PRODUCT_LABEL" - value: "error-reporting" -} -env_vars: { - key: "LANGUAGE_LABEL" - value: "python" -} - -################################################### - diff --git a/.kokoro/samples/python3.10/continuous.cfg b/.kokoro/samples/python3.10/continuous.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.10/continuous.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.10/periodic-head.cfg b/.kokoro/samples/python3.10/periodic-head.cfg deleted file mode 100644 index 0ab001ca..00000000 --- a/.kokoro/samples/python3.10/periodic-head.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# 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-error-reporting/.kokoro/test-samples-against-head.sh" -} diff --git a/.kokoro/samples/python3.10/periodic.cfg b/.kokoro/samples/python3.10/periodic.cfg deleted file mode 100644 index 71cd1e59..00000000 --- a/.kokoro/samples/python3.10/periodic.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "False" -} diff --git a/.kokoro/samples/python3.10/presubmit.cfg b/.kokoro/samples/python3.10/presubmit.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.10/presubmit.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.11/common.cfg b/.kokoro/samples/python3.11/common.cfg deleted file mode 100644 index d83d3eab..00000000 --- a/.kokoro/samples/python3.11/common.cfg +++ /dev/null @@ -1,59 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Specify which tests to run -env_vars: { - key: "RUN_TESTS_SESSION" - value: "py-3.11" -} - -# Declare build specific Cloud project. -env_vars: { - key: "BUILD_SPECIFIC_GCLOUD_PROJECT" - value: "python-docs-samples-tests-311" -} - -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-error-reporting/.kokoro/test-samples.sh" -} - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" -} - -# Download secrets for samples -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Use the trampoline script to run in docker. -build_file: "python-error-reporting/.kokoro/trampoline_v2.sh" - -############################################# -# this section merged from .kokoro/common_env_vars.cfg using owlbot.py - -env_vars: { - key: "PRODUCT_AREA_LABEL" - value: "observability" -} -env_vars: { - key: "PRODUCT_LABEL" - value: "error-reporting" -} -env_vars: { - key: "LANGUAGE_LABEL" - value: "python" -} - -################################################### - diff --git a/.kokoro/samples/python3.11/continuous.cfg b/.kokoro/samples/python3.11/continuous.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.11/continuous.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.11/periodic-head.cfg b/.kokoro/samples/python3.11/periodic-head.cfg deleted file mode 100644 index 0ab001ca..00000000 --- a/.kokoro/samples/python3.11/periodic-head.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# 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-error-reporting/.kokoro/test-samples-against-head.sh" -} diff --git a/.kokoro/samples/python3.11/periodic.cfg b/.kokoro/samples/python3.11/periodic.cfg deleted file mode 100644 index 71cd1e59..00000000 --- a/.kokoro/samples/python3.11/periodic.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "False" -} diff --git a/.kokoro/samples/python3.11/presubmit.cfg b/.kokoro/samples/python3.11/presubmit.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.11/presubmit.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.12/common.cfg b/.kokoro/samples/python3.12/common.cfg deleted file mode 100644 index 67d66075..00000000 --- a/.kokoro/samples/python3.12/common.cfg +++ /dev/null @@ -1,59 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Specify which tests to run -env_vars: { - key: "RUN_TESTS_SESSION" - value: "py-3.12" -} - -# Declare build specific Cloud project. -env_vars: { - key: "BUILD_SPECIFIC_GCLOUD_PROJECT" - value: "python-docs-samples-tests-312" -} - -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-error-reporting/.kokoro/test-samples.sh" -} - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" -} - -# Download secrets for samples -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Use the trampoline script to run in docker. -build_file: "python-error-reporting/.kokoro/trampoline_v2.sh" - -############################################# -# this section merged from .kokoro/common_env_vars.cfg using owlbot.py - -env_vars: { - key: "PRODUCT_AREA_LABEL" - value: "observability" -} -env_vars: { - key: "PRODUCT_LABEL" - value: "error-reporting" -} -env_vars: { - key: "LANGUAGE_LABEL" - value: "python" -} - -################################################### - diff --git a/.kokoro/samples/python3.12/continuous.cfg b/.kokoro/samples/python3.12/continuous.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.12/continuous.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.12/periodic-head.cfg b/.kokoro/samples/python3.12/periodic-head.cfg deleted file mode 100644 index 0ab001ca..00000000 --- a/.kokoro/samples/python3.12/periodic-head.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# 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-error-reporting/.kokoro/test-samples-against-head.sh" -} diff --git a/.kokoro/samples/python3.12/periodic.cfg b/.kokoro/samples/python3.12/periodic.cfg deleted file mode 100644 index 71cd1e59..00000000 --- a/.kokoro/samples/python3.12/periodic.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "False" -} diff --git a/.kokoro/samples/python3.12/presubmit.cfg b/.kokoro/samples/python3.12/presubmit.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.12/presubmit.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.13/common.cfg b/.kokoro/samples/python3.13/common.cfg deleted file mode 100644 index e83c889e..00000000 --- a/.kokoro/samples/python3.13/common.cfg +++ /dev/null @@ -1,60 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Specify which tests to run -env_vars: { - key: "RUN_TESTS_SESSION" - value: "py-3.13" -} - -# Declare build specific Cloud project. -env_vars: { - key: "BUILD_SPECIFIC_GCLOUD_PROJECT" - value: "python-docs-samples-tests-313" -} - -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-error-reporting/.kokoro/test-samples.sh" -} - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" -} - -# Download secrets for samples -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Use the trampoline script to run in docker. -build_file: "python-error-reporting/.kokoro/trampoline_v2.sh" - - -############################################# -# this section merged from .kokoro/common_env_vars.cfg using owlbot.py - -env_vars: { - key: "PRODUCT_AREA_LABEL" - value: "observability" -} -env_vars: { - key: "PRODUCT_LABEL" - value: "error-reporting" -} -env_vars: { - key: "LANGUAGE_LABEL" - value: "python" -} - -################################################### - diff --git a/.kokoro/samples/python3.13/continuous.cfg b/.kokoro/samples/python3.13/continuous.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.13/continuous.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.13/periodic-head.cfg b/.kokoro/samples/python3.13/periodic-head.cfg deleted file mode 100644 index 0ab001ca..00000000 --- a/.kokoro/samples/python3.13/periodic-head.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# 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-error-reporting/.kokoro/test-samples-against-head.sh" -} diff --git a/.kokoro/samples/python3.13/periodic.cfg b/.kokoro/samples/python3.13/periodic.cfg deleted file mode 100644 index 71cd1e59..00000000 --- a/.kokoro/samples/python3.13/periodic.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "False" -} diff --git a/.kokoro/samples/python3.13/presubmit.cfg b/.kokoro/samples/python3.13/presubmit.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.13/presubmit.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.14/common.cfg b/.kokoro/samples/python3.14/common.cfg deleted file mode 100644 index 09f706f6..00000000 --- a/.kokoro/samples/python3.14/common.cfg +++ /dev/null @@ -1,60 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Specify which tests to run -env_vars: { - key: "RUN_TESTS_SESSION" - value: "py-3.14" -} - -# Declare build specific Cloud project. -env_vars: { - key: "BUILD_SPECIFIC_GCLOUD_PROJECT" - value: "python-docs-samples-tests-314" -} - -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-error-reporting/.kokoro/test-samples.sh" -} - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" -} - -# Download secrets for samples -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Use the trampoline script to run in docker. -build_file: "python-error-reporting/.kokoro/trampoline_v2.sh" - - -############################################# -# this section merged from .kokoro/common_env_vars.cfg using owlbot.py - -env_vars: { - key: "PRODUCT_AREA_LABEL" - value: "observability" -} -env_vars: { - key: "PRODUCT_LABEL" - value: "error-reporting" -} -env_vars: { - key: "LANGUAGE_LABEL" - value: "python" -} - -################################################### - diff --git a/.kokoro/samples/python3.14/continuous.cfg b/.kokoro/samples/python3.14/continuous.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.14/continuous.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.14/periodic-head.cfg b/.kokoro/samples/python3.14/periodic-head.cfg deleted file mode 100644 index 0ab001ca..00000000 --- a/.kokoro/samples/python3.14/periodic-head.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# 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-error-reporting/.kokoro/test-samples-against-head.sh" -} diff --git a/.kokoro/samples/python3.14/periodic.cfg b/.kokoro/samples/python3.14/periodic.cfg deleted file mode 100644 index 71cd1e59..00000000 --- a/.kokoro/samples/python3.14/periodic.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "False" -} diff --git a/.kokoro/samples/python3.14/presubmit.cfg b/.kokoro/samples/python3.14/presubmit.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.14/presubmit.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.7/common.cfg b/.kokoro/samples/python3.7/common.cfg deleted file mode 100644 index ad162db9..00000000 --- a/.kokoro/samples/python3.7/common.cfg +++ /dev/null @@ -1,59 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Specify which tests to run -env_vars: { - key: "RUN_TESTS_SESSION" - value: "py-3.7" -} - -# Declare build specific Cloud project. -env_vars: { - key: "BUILD_SPECIFIC_GCLOUD_PROJECT" - value: "python-docs-samples-tests-py37" -} - -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-error-reporting/.kokoro/test-samples.sh" -} - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" -} - -# Download secrets for samples -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Use the trampoline script to run in docker. -build_file: "python-error-reporting/.kokoro/trampoline_v2.sh" - -############################################# -# this section merged from .kokoro/common_env_vars.cfg using owlbot.py - -env_vars: { - key: "PRODUCT_AREA_LABEL" - value: "observability" -} -env_vars: { - key: "PRODUCT_LABEL" - value: "error-reporting" -} -env_vars: { - key: "LANGUAGE_LABEL" - value: "python" -} - -################################################### - diff --git a/.kokoro/samples/python3.7/continuous.cfg b/.kokoro/samples/python3.7/continuous.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.7/continuous.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.7/periodic-head.cfg b/.kokoro/samples/python3.7/periodic-head.cfg deleted file mode 100644 index 0ab001ca..00000000 --- a/.kokoro/samples/python3.7/periodic-head.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# 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-error-reporting/.kokoro/test-samples-against-head.sh" -} diff --git a/.kokoro/samples/python3.7/periodic.cfg b/.kokoro/samples/python3.7/periodic.cfg deleted file mode 100644 index 71cd1e59..00000000 --- a/.kokoro/samples/python3.7/periodic.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "False" -} diff --git a/.kokoro/samples/python3.7/presubmit.cfg b/.kokoro/samples/python3.7/presubmit.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.7/presubmit.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.8/common.cfg b/.kokoro/samples/python3.8/common.cfg deleted file mode 100644 index b495960b..00000000 --- a/.kokoro/samples/python3.8/common.cfg +++ /dev/null @@ -1,59 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Specify which tests to run -env_vars: { - key: "RUN_TESTS_SESSION" - value: "py-3.8" -} - -# Declare build specific Cloud project. -env_vars: { - key: "BUILD_SPECIFIC_GCLOUD_PROJECT" - value: "python-docs-samples-tests-py38" -} - -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-error-reporting/.kokoro/test-samples.sh" -} - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" -} - -# Download secrets for samples -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Use the trampoline script to run in docker. -build_file: "python-error-reporting/.kokoro/trampoline_v2.sh" - -############################################# -# this section merged from .kokoro/common_env_vars.cfg using owlbot.py - -env_vars: { - key: "PRODUCT_AREA_LABEL" - value: "observability" -} -env_vars: { - key: "PRODUCT_LABEL" - value: "error-reporting" -} -env_vars: { - key: "LANGUAGE_LABEL" - value: "python" -} - -################################################### - diff --git a/.kokoro/samples/python3.8/continuous.cfg b/.kokoro/samples/python3.8/continuous.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.8/continuous.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.8/periodic-head.cfg b/.kokoro/samples/python3.8/periodic-head.cfg deleted file mode 100644 index 0ab001ca..00000000 --- a/.kokoro/samples/python3.8/periodic-head.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# 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-error-reporting/.kokoro/test-samples-against-head.sh" -} diff --git a/.kokoro/samples/python3.8/periodic.cfg b/.kokoro/samples/python3.8/periodic.cfg deleted file mode 100644 index 71cd1e59..00000000 --- a/.kokoro/samples/python3.8/periodic.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "False" -} diff --git a/.kokoro/samples/python3.8/presubmit.cfg b/.kokoro/samples/python3.8/presubmit.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.8/presubmit.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.9/common.cfg b/.kokoro/samples/python3.9/common.cfg deleted file mode 100644 index 01a9e9d3..00000000 --- a/.kokoro/samples/python3.9/common.cfg +++ /dev/null @@ -1,59 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Specify which tests to run -env_vars: { - key: "RUN_TESTS_SESSION" - value: "py-3.9" -} - -# Declare build specific Cloud project. -env_vars: { - key: "BUILD_SPECIFIC_GCLOUD_PROJECT" - value: "python-docs-samples-tests-py39" -} - -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/python-error-reporting/.kokoro/test-samples.sh" -} - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" -} - -# Download secrets for samples -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Use the trampoline script to run in docker. -build_file: "python-error-reporting/.kokoro/trampoline_v2.sh" - -############################################# -# this section merged from .kokoro/common_env_vars.cfg using owlbot.py - -env_vars: { - key: "PRODUCT_AREA_LABEL" - value: "observability" -} -env_vars: { - key: "PRODUCT_LABEL" - value: "error-reporting" -} -env_vars: { - key: "LANGUAGE_LABEL" - value: "python" -} - -################################################### - diff --git a/.kokoro/samples/python3.9/continuous.cfg b/.kokoro/samples/python3.9/continuous.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.9/continuous.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/samples/python3.9/periodic-head.cfg b/.kokoro/samples/python3.9/periodic-head.cfg deleted file mode 100644 index 0ab001ca..00000000 --- a/.kokoro/samples/python3.9/periodic-head.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# 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-error-reporting/.kokoro/test-samples-against-head.sh" -} diff --git a/.kokoro/samples/python3.9/periodic.cfg b/.kokoro/samples/python3.9/periodic.cfg deleted file mode 100644 index 71cd1e59..00000000 --- a/.kokoro/samples/python3.9/periodic.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "False" -} diff --git a/.kokoro/samples/python3.9/presubmit.cfg b/.kokoro/samples/python3.9/presubmit.cfg deleted file mode 100644 index a1c8d975..00000000 --- a/.kokoro/samples/python3.9/presubmit.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -env_vars: { - key: "INSTALL_LIBRARY_FROM_SOURCE" - value: "True" -} \ No newline at end of file diff --git a/.kokoro/test-samples-against-head.sh b/.kokoro/test-samples-against-head.sh deleted file mode 100755 index e9d8bd79..00000000 --- a/.kokoro/test-samples-against-head.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.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 - -exec .kokoro/test-samples-impl.sh diff --git a/.kokoro/test-samples-impl.sh b/.kokoro/test-samples-impl.sh deleted file mode 100755 index 53e365bc..00000000 --- a/.kokoro/test-samples-impl.sh +++ /dev/null @@ -1,103 +0,0 @@ -#!/bin/bash -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.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 don't exist -if ! find samples -name 'requirements.txt' | grep -q .; then - echo "No tests run. './samples/**/requirements.txt' 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 -# `virtualenv==20.26.6` is added for Python 3.7 compatibility -python3.9 -m pip install --upgrade --quiet nox virtualenv==20.26.6 - -# 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.9 -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/main/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 deleted file mode 100755 index 7933d820..00000000 --- a/.kokoro/test-samples.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.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. - -# 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 -set -eo pipefail -# Enables `**` to include files nested inside sub-folders -shopt -s globstar - -# 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 - 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 - -exec .kokoro/test-samples-impl.sh diff --git a/.kokoro/trampoline.sh b/.kokoro/trampoline.sh deleted file mode 100755 index 48f79699..00000000 --- a/.kokoro/trampoline.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -eo pipefail - -# Always run the cleanup script, regardless of the success of bouncing into -# the container. -function cleanup() { - chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh - ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh - echo "cleanup"; -} -trap cleanup EXIT - -$(dirname $0)/populate-secrets.sh # Secret Manager secrets. -python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" \ No newline at end of file diff --git a/.kokoro/trampoline_v2.sh b/.kokoro/trampoline_v2.sh deleted file mode 100755 index d03f92df..00000000 --- a/.kokoro/trampoline_v2.sh +++ /dev/null @@ -1,487 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# trampoline_v2.sh -# -# This script does 3 things. -# -# 1. Prepare the Docker image for the test -# 2. Run the Docker with appropriate flags to run the test -# 3. Upload the newly built Docker image -# -# in a way that is somewhat compatible with trampoline_v1. -# -# To run this script, first download few files from gcs to /dev/shm. -# (/dev/shm is passed into the container as KOKORO_GFILE_DIR). -# -# gcloud storage cp gs://cloud-devrel-kokoro-resources/python-docs-samples/secrets_viewer_service_account.json /dev/shm -# gcloud storage cp gs://cloud-devrel-kokoro-resources/python-docs-samples/automl_secrets.txt /dev/shm -# -# Then run the script. -# .kokoro/trampoline_v2.sh -# -# These environment variables are required: -# TRAMPOLINE_IMAGE: The docker image to use. -# TRAMPOLINE_DOCKERFILE: The location of the Dockerfile. -# -# You can optionally change these environment variables: -# TRAMPOLINE_IMAGE_UPLOAD: -# (true|false): Whether to upload the Docker image after the -# successful builds. -# TRAMPOLINE_BUILD_FILE: The script to run in the docker container. -# TRAMPOLINE_WORKSPACE: The workspace path in the docker container. -# Defaults to /workspace. -# Potentially there are some repo specific envvars in .trampolinerc in -# the project root. - - -set -euo pipefail - -TRAMPOLINE_VERSION="2.0.5" - -if command -v tput >/dev/null && [[ -n "${TERM:-}" ]]; then - readonly IO_COLOR_RED="$(tput setaf 1)" - readonly IO_COLOR_GREEN="$(tput setaf 2)" - readonly IO_COLOR_YELLOW="$(tput setaf 3)" - readonly IO_COLOR_RESET="$(tput sgr0)" -else - readonly IO_COLOR_RED="" - readonly IO_COLOR_GREEN="" - readonly IO_COLOR_YELLOW="" - readonly IO_COLOR_RESET="" -fi - -function function_exists { - [ $(LC_ALL=C type -t $1)"" == "function" ] -} - -# Logs a message using the given color. The first argument must be one -# of the IO_COLOR_* variables defined above, such as -# "${IO_COLOR_YELLOW}". The remaining arguments will be logged in the -# given color. The log message will also have an RFC-3339 timestamp -# prepended (in UTC). You can disable the color output by setting -# TERM=vt100. -function log_impl() { - local color="$1" - shift - local timestamp="$(date -u "+%Y-%m-%dT%H:%M:%SZ")" - echo "================================================================" - echo "${color}${timestamp}:" "$@" "${IO_COLOR_RESET}" - echo "================================================================" -} - -# Logs the given message with normal coloring and a timestamp. -function log() { - log_impl "${IO_COLOR_RESET}" "$@" -} - -# Logs the given message in green with a timestamp. -function log_green() { - log_impl "${IO_COLOR_GREEN}" "$@" -} - -# Logs the given message in yellow with a timestamp. -function log_yellow() { - log_impl "${IO_COLOR_YELLOW}" "$@" -} - -# Logs the given message in red with a timestamp. -function log_red() { - log_impl "${IO_COLOR_RED}" "$@" -} - -readonly tmpdir=$(mktemp -d -t ci-XXXXXXXX) -readonly tmphome="${tmpdir}/h" -mkdir -p "${tmphome}" - -function cleanup() { - rm -rf "${tmpdir}" -} -trap cleanup EXIT - -RUNNING_IN_CI="${RUNNING_IN_CI:-false}" - -# The workspace in the container, defaults to /workspace. -TRAMPOLINE_WORKSPACE="${TRAMPOLINE_WORKSPACE:-/workspace}" - -pass_down_envvars=( - # TRAMPOLINE_V2 variables. - # Tells scripts whether they are running as part of CI or not. - "RUNNING_IN_CI" - # Indicates which CI system we're in. - "TRAMPOLINE_CI" - # Indicates the version of the script. - "TRAMPOLINE_VERSION" -) - -log_yellow "Building with Trampoline ${TRAMPOLINE_VERSION}" - -# Detect which CI systems we're in. If we're in any of the CI systems -# we support, `RUNNING_IN_CI` will be true and `TRAMPOLINE_CI` will be -# the name of the CI system. Both envvars will be passing down to the -# container for telling which CI system we're in. -if [[ -n "${KOKORO_BUILD_ID:-}" ]]; then - # descriptive env var for indicating it's on CI. - RUNNING_IN_CI="true" - TRAMPOLINE_CI="kokoro" - if [[ "${TRAMPOLINE_USE_LEGACY_SERVICE_ACCOUNT:-}" == "true" ]]; then - if [[ ! -f "${KOKORO_GFILE_DIR}/kokoro-trampoline.service-account.json" ]]; then - log_red "${KOKORO_GFILE_DIR}/kokoro-trampoline.service-account.json does not exist. Did you forget to mount cloud-devrel-kokoro-resources/trampoline? Aborting." - exit 1 - fi - # This service account will be activated later. - TRAMPOLINE_SERVICE_ACCOUNT="${KOKORO_GFILE_DIR}/kokoro-trampoline.service-account.json" - else - if [[ "${TRAMPOLINE_VERBOSE:-}" == "true" ]]; then - gcloud auth list - fi - log_yellow "Configuring Container Registry access" - gcloud auth configure-docker --quiet - fi - pass_down_envvars+=( - # KOKORO dynamic variables. - "KOKORO_BUILD_NUMBER" - "KOKORO_BUILD_ID" - "KOKORO_JOB_NAME" - "KOKORO_GIT_COMMIT" - "KOKORO_GITHUB_COMMIT" - "KOKORO_GITHUB_PULL_REQUEST_NUMBER" - "KOKORO_GITHUB_PULL_REQUEST_COMMIT" - # For FlakyBot - "KOKORO_GITHUB_COMMIT_URL" - "KOKORO_GITHUB_PULL_REQUEST_URL" - ) -elif [[ "${TRAVIS:-}" == "true" ]]; then - RUNNING_IN_CI="true" - TRAMPOLINE_CI="travis" - pass_down_envvars+=( - "TRAVIS_BRANCH" - "TRAVIS_BUILD_ID" - "TRAVIS_BUILD_NUMBER" - "TRAVIS_BUILD_WEB_URL" - "TRAVIS_COMMIT" - "TRAVIS_COMMIT_MESSAGE" - "TRAVIS_COMMIT_RANGE" - "TRAVIS_JOB_NAME" - "TRAVIS_JOB_NUMBER" - "TRAVIS_JOB_WEB_URL" - "TRAVIS_PULL_REQUEST" - "TRAVIS_PULL_REQUEST_BRANCH" - "TRAVIS_PULL_REQUEST_SHA" - "TRAVIS_PULL_REQUEST_SLUG" - "TRAVIS_REPO_SLUG" - "TRAVIS_SECURE_ENV_VARS" - "TRAVIS_TAG" - ) -elif [[ -n "${GITHUB_RUN_ID:-}" ]]; then - RUNNING_IN_CI="true" - TRAMPOLINE_CI="github-workflow" - pass_down_envvars+=( - "GITHUB_WORKFLOW" - "GITHUB_RUN_ID" - "GITHUB_RUN_NUMBER" - "GITHUB_ACTION" - "GITHUB_ACTIONS" - "GITHUB_ACTOR" - "GITHUB_REPOSITORY" - "GITHUB_EVENT_NAME" - "GITHUB_EVENT_PATH" - "GITHUB_SHA" - "GITHUB_REF" - "GITHUB_HEAD_REF" - "GITHUB_BASE_REF" - ) -elif [[ "${CIRCLECI:-}" == "true" ]]; then - RUNNING_IN_CI="true" - TRAMPOLINE_CI="circleci" - pass_down_envvars+=( - "CIRCLE_BRANCH" - "CIRCLE_BUILD_NUM" - "CIRCLE_BUILD_URL" - "CIRCLE_COMPARE_URL" - "CIRCLE_JOB" - "CIRCLE_NODE_INDEX" - "CIRCLE_NODE_TOTAL" - "CIRCLE_PREVIOUS_BUILD_NUM" - "CIRCLE_PROJECT_REPONAME" - "CIRCLE_PROJECT_USERNAME" - "CIRCLE_REPOSITORY_URL" - "CIRCLE_SHA1" - "CIRCLE_STAGE" - "CIRCLE_USERNAME" - "CIRCLE_WORKFLOW_ID" - "CIRCLE_WORKFLOW_JOB_ID" - "CIRCLE_WORKFLOW_UPSTREAM_JOB_IDS" - "CIRCLE_WORKFLOW_WORKSPACE_ID" - ) -fi - -# Configure the service account for pulling the docker image. -function repo_root() { - local dir="$1" - while [[ ! -d "${dir}/.git" ]]; do - dir="$(dirname "$dir")" - done - echo "${dir}" -} - -# Detect the project root. In CI builds, we assume the script is in -# the git tree and traverse from there, otherwise, traverse from `pwd` -# to find `.git` directory. -if [[ "${RUNNING_IN_CI:-}" == "true" ]]; then - PROGRAM_PATH="$(realpath "$0")" - PROGRAM_DIR="$(dirname "${PROGRAM_PATH}")" - PROJECT_ROOT="$(repo_root "${PROGRAM_DIR}")" -else - PROJECT_ROOT="$(repo_root $(pwd))" -fi - -log_yellow "Changing to the project root: ${PROJECT_ROOT}." -cd "${PROJECT_ROOT}" - -# To support relative path for `TRAMPOLINE_SERVICE_ACCOUNT`, we need -# to use this environment variable in `PROJECT_ROOT`. -if [[ -n "${TRAMPOLINE_SERVICE_ACCOUNT:-}" ]]; then - - mkdir -p "${tmpdir}/gcloud" - gcloud_config_dir="${tmpdir}/gcloud" - - log_yellow "Using isolated gcloud config: ${gcloud_config_dir}." - export CLOUDSDK_CONFIG="${gcloud_config_dir}" - - log_yellow "Using ${TRAMPOLINE_SERVICE_ACCOUNT} for authentication." - gcloud auth activate-service-account \ - --key-file "${TRAMPOLINE_SERVICE_ACCOUNT}" - log_yellow "Configuring Container Registry access" - gcloud auth configure-docker --quiet -fi - -required_envvars=( - # The basic trampoline configurations. - "TRAMPOLINE_IMAGE" - "TRAMPOLINE_BUILD_FILE" -) - -if [[ -f "${PROJECT_ROOT}/.trampolinerc" ]]; then - source "${PROJECT_ROOT}/.trampolinerc" -fi - -log_yellow "Checking environment variables." -for e in "${required_envvars[@]}" -do - if [[ -z "${!e:-}" ]]; then - log "Missing ${e} env var. Aborting." - exit 1 - fi -done - -# We want to support legacy style TRAMPOLINE_BUILD_FILE used with V1 -# script: e.g. "github/repo-name/.kokoro/run_tests.sh" -TRAMPOLINE_BUILD_FILE="${TRAMPOLINE_BUILD_FILE#github/*/}" -log_yellow "Using TRAMPOLINE_BUILD_FILE: ${TRAMPOLINE_BUILD_FILE}" - -# ignore error on docker operations and test execution -set +e - -log_yellow "Preparing Docker image." -# We only download the docker image in CI builds. -if [[ "${RUNNING_IN_CI:-}" == "true" ]]; then - # Download the docker image specified by `TRAMPOLINE_IMAGE` - - # We may want to add --max-concurrent-downloads flag. - - log_yellow "Start pulling the Docker image: ${TRAMPOLINE_IMAGE}." - if docker pull "${TRAMPOLINE_IMAGE}"; then - log_green "Finished pulling the Docker image: ${TRAMPOLINE_IMAGE}." - has_image="true" - else - log_red "Failed pulling the Docker image: ${TRAMPOLINE_IMAGE}." - has_image="false" - fi -else - # For local run, check if we have the image. - if docker images "${TRAMPOLINE_IMAGE}:latest" | grep "${TRAMPOLINE_IMAGE}"; then - has_image="true" - else - has_image="false" - fi -fi - - -# The default user for a Docker container has uid 0 (root). To avoid -# creating root-owned files in the build directory we tell docker to -# use the current user ID. -user_uid="$(id -u)" -user_gid="$(id -g)" -user_name="$(id -un)" - -# To allow docker in docker, we add the user to the docker group in -# the host os. -docker_gid=$(cut -d: -f3 < <(getent group docker)) - -update_cache="false" -if [[ "${TRAMPOLINE_DOCKERFILE:-none}" != "none" ]]; then - # Build the Docker image from the source. - context_dir=$(dirname "${TRAMPOLINE_DOCKERFILE}") - docker_build_flags=( - "-f" "${TRAMPOLINE_DOCKERFILE}" - "-t" "${TRAMPOLINE_IMAGE}" - "--build-arg" "UID=${user_uid}" - "--build-arg" "USERNAME=${user_name}" - ) - if [[ "${has_image}" == "true" ]]; then - docker_build_flags+=("--cache-from" "${TRAMPOLINE_IMAGE}") - fi - - log_yellow "Start building the docker image." - if [[ "${TRAMPOLINE_VERBOSE:-false}" == "true" ]]; then - echo "docker build" "${docker_build_flags[@]}" "${context_dir}" - fi - - # ON CI systems, we want to suppress docker build logs, only - # output the logs when it fails. - if [[ "${RUNNING_IN_CI:-}" == "true" ]]; then - if docker build "${docker_build_flags[@]}" "${context_dir}" \ - > "${tmpdir}/docker_build.log" 2>&1; then - if [[ "${TRAMPOLINE_VERBOSE:-}" == "true" ]]; then - cat "${tmpdir}/docker_build.log" - fi - - log_green "Finished building the docker image." - update_cache="true" - else - log_red "Failed to build the Docker image, aborting." - log_yellow "Dumping the build logs:" - cat "${tmpdir}/docker_build.log" - exit 1 - fi - else - if docker build "${docker_build_flags[@]}" "${context_dir}"; then - log_green "Finished building the docker image." - update_cache="true" - else - log_red "Failed to build the Docker image, aborting." - exit 1 - fi - fi -else - if [[ "${has_image}" != "true" ]]; then - log_red "We do not have ${TRAMPOLINE_IMAGE} locally, aborting." - exit 1 - fi -fi - -# We use an array for the flags so they are easier to document. -docker_flags=( - # Remove the container after it exists. - "--rm" - - # Use the host network. - "--network=host" - - # Run in priviledged mode. We are not using docker for sandboxing or - # isolation, just for packaging our dev tools. - "--privileged" - - # Run the docker script with the user id. Because the docker image gets to - # write in ${PWD} you typically want this to be your user id. - # To allow docker in docker, we need to use docker gid on the host. - "--user" "${user_uid}:${docker_gid}" - - # Pass down the USER. - "--env" "USER=${user_name}" - - # Mount the project directory inside the Docker container. - "--volume" "${PROJECT_ROOT}:${TRAMPOLINE_WORKSPACE}" - "--workdir" "${TRAMPOLINE_WORKSPACE}" - "--env" "PROJECT_ROOT=${TRAMPOLINE_WORKSPACE}" - - # Mount the temporary home directory. - "--volume" "${tmphome}:/h" - "--env" "HOME=/h" - - # Allow docker in docker. - "--volume" "/var/run/docker.sock:/var/run/docker.sock" - - # Mount the /tmp so that docker in docker can mount the files - # there correctly. - "--volume" "/tmp:/tmp" - # Pass down the KOKORO_GFILE_DIR and KOKORO_KEYSTORE_DIR - # TODO(tmatsuo): This part is not portable. - "--env" "TRAMPOLINE_SECRET_DIR=/secrets" - "--volume" "${KOKORO_GFILE_DIR:-/dev/shm}:/secrets/gfile" - "--env" "KOKORO_GFILE_DIR=/secrets/gfile" - "--volume" "${KOKORO_KEYSTORE_DIR:-/dev/shm}:/secrets/keystore" - "--env" "KOKORO_KEYSTORE_DIR=/secrets/keystore" -) - -# Add an option for nicer output if the build gets a tty. -if [[ -t 0 ]]; then - docker_flags+=("-it") -fi - -# Passing down env vars -for e in "${pass_down_envvars[@]}" -do - if [[ -n "${!e:-}" ]]; then - docker_flags+=("--env" "${e}=${!e}") - fi -done - -# If arguments are given, all arguments will become the commands run -# in the container, otherwise run TRAMPOLINE_BUILD_FILE. -if [[ $# -ge 1 ]]; then - log_yellow "Running the given commands '" "${@:1}" "' in the container." - readonly commands=("${@:1}") - if [[ "${TRAMPOLINE_VERBOSE:-}" == "true" ]]; then - echo docker run "${docker_flags[@]}" "${TRAMPOLINE_IMAGE}" "${commands[@]}" - fi - docker run "${docker_flags[@]}" "${TRAMPOLINE_IMAGE}" "${commands[@]}" -else - log_yellow "Running the tests in a Docker container." - docker_flags+=("--entrypoint=${TRAMPOLINE_BUILD_FILE}") - if [[ "${TRAMPOLINE_VERBOSE:-}" == "true" ]]; then - echo docker run "${docker_flags[@]}" "${TRAMPOLINE_IMAGE}" - fi - docker run "${docker_flags[@]}" "${TRAMPOLINE_IMAGE}" -fi - - -test_retval=$? - -if [[ ${test_retval} -eq 0 ]]; then - log_green "Build finished with ${test_retval}" -else - log_red "Build finished with ${test_retval}" -fi - -# Only upload it when the test passes. -if [[ "${update_cache}" == "true" ]] && \ - [[ $test_retval == 0 ]] && \ - [[ "${TRAMPOLINE_IMAGE_UPLOAD:-false}" == "true" ]]; then - log_yellow "Uploading the Docker image." - if docker push "${TRAMPOLINE_IMAGE}"; then - log_green "Finished uploading the Docker image." - else - log_red "Failed uploading the Docker image." - fi - # Call trampoline_after_upload_hook if it's defined. - if function_exists trampoline_after_upload_hook; then - trampoline_after_upload_hook - fi - -fi - -exit "${test_retval}" diff --git a/.librarian/generator-input/.repo-metadata.json b/.librarian/generator-input/.repo-metadata.json deleted file mode 100644 index 5161e69d..00000000 --- a/.librarian/generator-input/.repo-metadata.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "clouderrorreporting", - "name_pretty": "Error Reporting", - "product_documentation": "https://cloud.google.com/error-reporting", - "client_documentation": "https://cloud.google.com/python/docs/reference/clouderrorreporting/latest", - "issue_tracker": "https://issuetracker.google.com/savedsearches/559780", - "release_level": "preview", - "language": "python", - "library_type": "GAPIC_COMBO", - "repo": "googleapis/python-error-reporting", - "distribution_name": "google-cloud-error-reporting", - "api_id": "clouderrorreporting.googleapis.com", - "requires_billing": false, - "codeowner_team": "@googleapis/yoshi-python", - "default_version": "v1beta1", - "api_shortname": "clouderrorreporting", - "api_description": "counts, analyzes and aggregates the crashes in your running cloud services. A centralized error management interface displays the results with sorting and filtering capabilities. A dedicated view shows the error details: time chart, occurrences, affected user count, first and last seen dates and a cleaned exception stack trace. Opt-in to receive email and mobile alerts on new errors." -} diff --git a/.librarian/generator-input/librarian.py b/.librarian/generator-input/librarian.py deleted file mode 100644 index 76977beb..00000000 --- a/.librarian/generator-input/librarian.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -import os -from pathlib import Path -import shutil - -import synthtool as s -import synthtool.gcp as gcp -from synthtool.languages import python - -# ---------------------------------------------------------------------------- -# Copy the generated client from the owl-bot staging directory -# ---------------------------------------------------------------------------- - -clean_up_generated_samples = True - -# Load the default version defined in .repo-metadata.json. -default_version = json.load(open(".repo-metadata.json", "rt")).get("default_version") - -for library in s.get_staging_dirs(default_version): - if clean_up_generated_samples: - shutil.rmtree("samples/generated_samples", ignore_errors=True) - clean_up_generated_samples = False - - s.move( - [library], - excludes=[ - "docs/index.rst", - "google/cloud/errorreporting/", - "setup.py", - "testing/constraints-3.7.txt", - "testing/constraints-3.8.txt", - "noxfile.py", - ], - ) -s.remove_staging_dirs() - -# ---------------------------------------------------------------------------- -# Add templated files -# ---------------------------------------------------------------------------- - -templated_files = gcp.CommonTemplates().py_library( - cov_level=100, - microgenerator=True, - versions=gcp.common.detect_versions(path="./google", default_first=True), -) -s.move( - templated_files, - excludes=[ - ".coveragerc", - ".github/**", - ".kokoro/**", - "docs/conf.py", - "docs/index.rst", - "testing/constraints-3.7.txt", - ], -) - -python.py_samples(skip_readmes=True) - -# run format session for all directories which have a noxfile -for noxfile in Path(".").glob("**/noxfile.py"): - s.shell.run(["nox", "-s", "blacken"], cwd=noxfile.parent, hide_output=False) diff --git a/.librarian/generator-input/noxfile.py b/.librarian/generator-input/noxfile.py deleted file mode 100644 index 35c5330b..00000000 --- a/.librarian/generator-input/noxfile.py +++ /dev/null @@ -1,487 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# 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! - -from __future__ import absolute_import - -import os -import pathlib -import re -import shutil -from typing import Dict, List -import warnings - -import nox - -FLAKE8_VERSION = "flake8==6.1.0" -BLACK_VERSION = "black[jupyter]==23.7.0" -ISORT_VERSION = "isort==5.11.0" -LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] - -DEFAULT_PYTHON_VERSION = "3.14" - -UNIT_TEST_PYTHON_VERSIONS: List[str] = [ - "3.7", - "3.8", - "3.9", - "3.10", - "3.11", - "3.12", - "3.13", - "3.14", -] -UNIT_TEST_STANDARD_DEPENDENCIES = [ - "mock", - "asyncmock", - "pytest", - "pytest-cov", - "pytest-asyncio", -] -UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] -UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = [] -UNIT_TEST_DEPENDENCIES: List[str] = [] -UNIT_TEST_EXTRAS: List[str] = [] -UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} - -SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.14"] -SYSTEM_TEST_STANDARD_DEPENDENCIES: List[str] = [ - "mock", - "pytest", - "google-cloud-testutils", -] -SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] -SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] -SYSTEM_TEST_DEPENDENCIES: List[str] = [] -SYSTEM_TEST_EXTRAS: List[str] = [] -SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} - -CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() - -nox.options.sessions = [ - "system", -] - -# Error if a python version is missing -nox.options.error_on_missing_interpreters = True - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def lint(session): - """Run linters. - - Returns a failure if the linters find linting errors or sufficiently - serious code quality issues. - """ - session.install(FLAKE8_VERSION, BLACK_VERSION) - session.run( - "black", - "--check", - *LINT_PATHS, - ) - session.run("flake8", "google", "tests") - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def blacken(session): - """Run black. Format code to uniform standard.""" - session.install(BLACK_VERSION) - session.run( - "black", - *LINT_PATHS, - ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def format(session): - """ - Run isort to sort imports. Then run black - to format code to uniform standard. - """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections - session.run( - "isort", - "--fss", - *LINT_PATHS, - ) - session.run( - "black", - *LINT_PATHS, - ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def lint_setup_py(session): - """Verify that setup.py is valid (including RST check).""" - session.install("docutils", "pygments", "setuptools") - session.run("python", "setup.py", "check", "--restructuredtext", "--strict") - - -def install_unittest_dependencies(session, *constraints): - standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES - session.install(*standard_deps, *constraints) - - if UNIT_TEST_EXTERNAL_DEPENDENCIES: - warnings.warn( - "'unit_test_external_dependencies' is deprecated. Instead, please " - "use 'unit_test_dependencies' or 'unit_test_local_dependencies'.", - DeprecationWarning, - ) - session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints) - - if UNIT_TEST_LOCAL_DEPENDENCIES: - session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints) - - if UNIT_TEST_EXTRAS_BY_PYTHON: - extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, []) - elif UNIT_TEST_EXTRAS: - extras = UNIT_TEST_EXTRAS - else: - extras = [] - - if extras: - session.install("-e", f".[{','.join(extras)}]", *constraints) - else: - session.install("-e", ".", *constraints) - - -@nox.session(python=UNIT_TEST_PYTHON_VERSIONS) -@nox.parametrize( - "protobuf_implementation", - ["python", "upb", "cpp"], -) -def unit(session, protobuf_implementation): - # Install all test dependencies, then install this package in-place. - - if protobuf_implementation == "cpp" and session.python in ( - "3.11", - "3.12", - "3.13", - "3.14", - ): - session.skip("cpp implementation is not supported in python 3.11+") - - constraints_path = str( - CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" - ) - install_unittest_dependencies(session, "-c", constraints_path) - - # TODO(https://github.com/googleapis/synthtool/issues/1976): - # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. - # The 'cpp' implementation requires Protobuf<4. - if protobuf_implementation == "cpp": - session.install("protobuf<4") - - # Run py.test against the unit tests. - session.run( - "py.test", - "--quiet", - f"--junitxml=unit_{session.python}_sponge_log.xml", - "--cov=google", - "--cov=tests/unit", - "--cov-append", - "--cov-config=.coveragerc", - "--cov-report=", - "--cov-fail-under=0", - os.path.join("tests", "unit"), - *session.posargs, - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - - -def install_systemtest_dependencies(session, *constraints): - # Use pre-release gRPC for system tests. - # Exclude version 1.52.0rc1 which has a known issue. - # See https://github.com/grpc/grpc/issues/32163 - session.install("--pre", "grpcio!=1.52.0rc1") - - session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints) - - if SYSTEM_TEST_EXTERNAL_DEPENDENCIES: - session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints) - - if SYSTEM_TEST_LOCAL_DEPENDENCIES: - session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints) - - if SYSTEM_TEST_DEPENDENCIES: - session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints) - - if SYSTEM_TEST_EXTRAS_BY_PYTHON: - extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, []) - elif SYSTEM_TEST_EXTRAS: - extras = SYSTEM_TEST_EXTRAS - else: - extras = [] - - if extras: - session.install("-e", f".[{','.join(extras)}]", *constraints) - else: - session.install("-e", ".", *constraints) - - -@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) -def system(session): - """Run the system test suite.""" - constraints_path = str( - CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" - ) - system_test_path = os.path.join("tests", "system.py") - system_test_folder_path = os.path.join("tests", "system") - - # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. - if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": - session.skip("RUN_SYSTEM_TESTS is set to false, skipping") - # 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) - # Sanity check: only run tests if found. - if not system_test_exists and not system_test_folder_exists: - session.skip("System tests were not found") - - install_systemtest_dependencies(session, "-c", constraints_path) - - # Run py.test against the system tests. - if system_test_exists: - 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", - f"--junitxml=system_{session.python}_sponge_log.xml", - system_test_folder_path, - *session.posargs, - ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def cover(session): - """Run the final coverage report. - - This outputs the coverage report aggregating coverage from the unit - test runs (not system test runs), and then erases coverage data. - """ - session.install("coverage", "pytest-cov") - session.run("coverage", "report", "--show-missing", "--fail-under=100") - - session.run("coverage", "erase") - - -@nox.session(python="3.10") -def docs(session): - """Build the docs for this library.""" - - session.install("-e", ".") - session.install( - # We need to pin to specific versions of the `sphinxcontrib-*` packages - # which still support sphinx 4.x. - # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 - # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. - "sphinxcontrib-applehelp==1.0.4", - "sphinxcontrib-devhelp==1.0.2", - "sphinxcontrib-htmlhelp==2.0.1", - "sphinxcontrib-qthelp==1.0.3", - "sphinxcontrib-serializinghtml==1.1.5", - "sphinx==4.5.0", - "alabaster", - "recommonmark", - ) - - shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) - session.run( - "sphinx-build", - "-W", # warnings as errors - "-T", # show full traceback on exception - "-N", # no colors - "-b", - "html", - "-d", - os.path.join("docs", "_build", "doctrees", ""), - os.path.join("docs", ""), - os.path.join("docs", "_build", "html", ""), - ) - - -@nox.session(python="3.10") -def docfx(session): - """Build the docfx yaml files for this library.""" - - session.install("-e", ".") - session.install( - # We need to pin to specific versions of the `sphinxcontrib-*` packages - # which still support sphinx 4.x. - # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 - # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. - "sphinxcontrib-applehelp==1.0.4", - "sphinxcontrib-devhelp==1.0.2", - "sphinxcontrib-htmlhelp==2.0.1", - "sphinxcontrib-qthelp==1.0.3", - "sphinxcontrib-serializinghtml==1.1.5", - "gcp-sphinx-docfx-yaml", - "alabaster", - "recommonmark", - ) - - shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) - session.run( - "sphinx-build", - "-T", # show full traceback on exception - "-N", # no colors - "-D", - ( - "extensions=sphinx.ext.autodoc," - "sphinx.ext.autosummary," - "docfx_yaml.extension," - "sphinx.ext.intersphinx," - "sphinx.ext.coverage," - "sphinx.ext.napoleon," - "sphinx.ext.todo," - "sphinx.ext.viewcode," - "recommonmark" - ), - "-b", - "html", - "-d", - os.path.join("docs", "_build", "doctrees", ""), - os.path.join("docs", ""), - os.path.join("docs", "_build", "html", ""), - ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -@nox.parametrize( - "protobuf_implementation", - ["python", "upb", "cpp"], -) -def prerelease_deps(session, protobuf_implementation): - """Run all tests with prerelease versions of dependencies installed.""" - - if protobuf_implementation == "cpp" and session.python in ( - "3.11", - "3.12", - "3.13", - "3.14", - ): - session.skip("cpp implementation is not supported in python 3.11+") - - # Install all dependencies - session.install("-e", ".[all, tests, tracing]") - unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES - session.install(*unit_deps_all) - system_deps_all = ( - SYSTEM_TEST_STANDARD_DEPENDENCIES + SYSTEM_TEST_EXTERNAL_DEPENDENCIES - ) - session.install(*system_deps_all) - - # Because we test minimum dependency versions on the minimum Python - # version, the first version we test with in the unit tests sessions has a - # constraints file containing all dependencies and extras. - with open( - CURRENT_DIRECTORY - / "testing" - / f"constraints-{UNIT_TEST_PYTHON_VERSIONS[0]}.txt", - encoding="utf-8", - ) as constraints_file: - constraints_text = constraints_file.read() - - # Ignore leading whitespace and comment lines. - constraints_deps = [ - match.group(1) - for match in re.finditer( - r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE - ) - ] - - session.install(*constraints_deps) - - prerel_deps = [ - "protobuf", - # dependency of grpc - "six", - "grpc-google-iam-v1", - "googleapis-common-protos", - "grpcio", - "grpcio-status", - "google-api-core", - "google-auth", - "proto-plus", - "google-cloud-testutils", - # dependencies of google-cloud-testutils" - "click", - ] - - for dep in prerel_deps: - session.install("--pre", "--no-deps", "--upgrade", dep) - - # Remaining dependencies - other_deps = [ - "requests", - ] - session.install(*other_deps) - - # Print out prerelease package versions - session.run( - "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" - ) - session.run("python", "-c", "import grpc; print(grpc.__version__)") - session.run("python", "-c", "import google.auth; print(google.auth.__version__)") - - session.run( - "py.test", - "tests/unit", - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - - system_test_path = os.path.join("tests", "system.py") - system_test_folder_path = os.path.join("tests", "system") - - # Only run system tests if found. - if os.path.exists(system_test_path): - session.run( - "py.test", - "--verbose", - f"--junitxml=system_{session.python}_sponge_log.xml", - system_test_path, - *session.posargs, - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - if os.path.exists(system_test_folder_path): - session.run( - "py.test", - "--verbose", - f"--junitxml=system_{session.python}_sponge_log.xml", - system_test_folder_path, - *session.posargs, - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) diff --git a/.librarian/generator-input/setup.py b/.librarian/generator-input/setup.py deleted file mode 100644 index c80d2b25..00000000 --- a/.librarian/generator-input/setup.py +++ /dev/null @@ -1,99 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import io -import os - -import setuptools # type: ignore - -package_root = os.path.abspath(os.path.dirname(__file__)) - -name = "google-cloud-error-reporting" - - -description = "Google Cloud Error Reporting API client library" - -version = {} -with open( - os.path.join(package_root, "google/cloud/error_reporting/gapic_version.py") -) as fp: - exec(fp.read(), version) -version = version["__version__"] - -if version[0] == "0": - release_status = "Development Status :: 4 - Beta" -else: - release_status = "Development Status :: 5 - Production/Stable" - -dependencies = [ - "google-cloud-logging>=1.14.0, <4.0.0", - # Exclude incompatible versions of `google-auth` - # See https://github.com/googleapis/google-cloud-python/issues/12364 - "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", - "google-api-core[grpc] >= 1.34.0, <3.0.0,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", - "grpcio >= 1.33.2, < 2.0.0", - "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.0, <2.0.0", - "proto-plus >= 1.22.2, <2.0.0; python_version>='3.11'", - "proto-plus >= 1.25.0, <2.0.0dev; python_version>='3.13'", - "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", -] -url = "https://github.com/googleapis/python-error-reporting" - -package_root = os.path.abspath(os.path.dirname(__file__)) - -readme_filename = os.path.join(package_root, "README.rst") -with io.open(readme_filename, encoding="utf-8") as readme_file: - readme = readme_file.read() - -packages = [ - package - for package in setuptools.find_namespace_packages() - if package.startswith("google") -] - -setuptools.setup( - name=name, - version=version, - description=description, - long_description=readme, - author="Google LLC", - author_email="googleapis-packages@google.com", - license="Apache 2.0", - url=url, - classifiers=[ - release_status, - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Programming Language :: Python :: 3.14", - "Operating System :: OS Independent", - "Topic :: Internet", - ], - platforms="Posix; MacOS X; Windows", - packages=packages, - python_requires=">=3.7", - install_requires=dependencies, - include_package_data=True, - zip_safe=False, -) diff --git a/.librarian/state.yaml b/.librarian/state.yaml deleted file mode 100644 index 7342d2e6..00000000 --- a/.librarian/state.yaml +++ /dev/null @@ -1,42 +0,0 @@ -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:a38add811f7f139d6a385b22d283ad09ef305b8cf50382ef62f0ce690787f021 -libraries: - - id: google-cloud-error-reporting - version: 1.14.0 - last_generated_commit: cf0434f4bd20618db60ddd16a1e7db2c0dfb9158 - apis: - - path: google/devtools/clouderrorreporting/v1beta1 - service_config: clouderrorreporting_v1beta1.yaml - source_roots: - - . - preserve_regex: [] - remove_regex: - - ^google/cloud/errorreporting_v1beta1 - - ^docs/_static - - ^docs/_templates - - ^docs/errorreporting_v1beta1 - - ^docs/multiprocessing.rst - - ^docs/conf.py - - ^docs/README.rst - - ^docs/summary_overview.md - - ^tests/unit/gapic - - ^tests/__init__.py - - ^tests/unit/__init__.py - - ^.coveragerc - - ^.flake8 - - ^.pre-commit-config.yaml - - ^.repo-metadata.json - - ^.trampolinerc - - ^LICENSE - - ^MANIFEST.in - - ^README.rst - - ^SECURITY.md - - ^mypy.ini - - ^noxfile.py - - ^owlbot.py - - ^renovate.json - - ^samples/generated_samples - - ^scripts/fixup_ - - ^setup.py - - ^testing/constraints-3.9 - - ^testing/constraints-3.1 - tag_format: v{version} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index 1d74695f..00000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# See https://pre-commit.com for more information -# See https://pre-commit.com/hooks.html for more hooks -repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-yaml -- repo: https://github.com/psf/black - rev: 23.7.0 - hooks: - - id: black -- repo: https://github.com/pycqa/flake8 - rev: 6.1.0 - hooks: - - id: flake8 diff --git a/.trampolinerc b/.trampolinerc deleted file mode 100644 index 00801523..00000000 --- a/.trampolinerc +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Add required env vars here. -required_envvars+=( -) - -# Add env vars which are passed down into the container here. -pass_down_envvars+=( - "NOX_SESSION" - ############### - # Docs builds - ############### - "STAGING_BUCKET" - "V2_STAGING_BUCKET" - ################## - # Samples builds - ################## - "INSTALL_LIBRARY_FROM_SOURCE" - "RUN_TESTS_SESSION" - "BUILD_SPECIFIC_GCLOUD_PROJECT" - # Target directories. - "RUN_TESTS_DIRS" - # The nox session to run. - "RUN_TESTS_SESSION" -) - -# Prevent unintentional override on the default image. -if [[ "${TRAMPOLINE_IMAGE_UPLOAD:-false}" == "true" ]] && \ - [[ -z "${TRAMPOLINE_IMAGE:-}" ]]; then - echo "Please set TRAMPOLINE_IMAGE if you want to upload the Docker image." - exit 1 -fi - -# Define the default value if it makes sense. -if [[ -z "${TRAMPOLINE_IMAGE_UPLOAD:-}" ]]; then - TRAMPOLINE_IMAGE_UPLOAD="" -fi - -if [[ -z "${TRAMPOLINE_IMAGE:-}" ]]; then - TRAMPOLINE_IMAGE="" -fi - -if [[ -z "${TRAMPOLINE_DOCKERFILE:-}" ]]; then - TRAMPOLINE_DOCKERFILE="" -fi - -if [[ -z "${TRAMPOLINE_BUILD_FILE:-}" ]]; then - TRAMPOLINE_BUILD_FILE="" -fi diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index dca4a7fe..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,519 +0,0 @@ -# Changelog - -[PyPI History][1] - -[1]: https://pypi.org/project/google-cloud-error-reporting/#history - -## [1.14.0](https://github.com/googleapis/python-error-reporting/compare/v1.13.0...v1.14.0) (2025-12-16) - - -### Features - -* support mTLS certificates when available (#717) ([7e99258b41ddef55b63c70c7e31afced4ab30103](https://github.com/googleapis/python-error-reporting/commit/7e99258b41ddef55b63c70c7e31afced4ab30103)) - -## [1.13.0](https://github.com/googleapis/python-error-reporting/compare/v1.12.0...v1.13.0) (2025-11-12) - - -### Features - -* Add support for Python 3.14 ([#712](https://github.com/googleapis/python-error-reporting/issues/712)) ([e8b4762](https://github.com/googleapis/python-error-reporting/commit/e8b4762d289755377acb7c69744a347fbe6651d6)) - - -### Bug Fixes - -* Deprecate credentials_file argument ([f86c964](https://github.com/googleapis/python-error-reporting/commit/f86c964200cc16488e46fdd95ad78e7975760b53)) - -## [1.12.0](https://github.com/googleapis/python-error-reporting/compare/v1.11.1...v1.12.0) (2025-05-21) - - -### Features - -* Add REST Interceptors which support reading metadata ([1d120c7](https://github.com/googleapis/python-error-reporting/commit/1d120c77c73b566796b32cab017a0d4cdfa28713)) -* Add support for opt-in debug logging ([1d120c7](https://github.com/googleapis/python-error-reporting/commit/1d120c77c73b566796b32cab017a0d4cdfa28713)) - - -### Bug Fixes - -* Allow Protobuf 6.x ([#557](https://github.com/googleapis/python-error-reporting/issues/557)) ([9f8faeb](https://github.com/googleapis/python-error-reporting/commit/9f8faeba223a0e1834c0750d21b5cafdee74d327)) -* Fix typing issue with gRPC metadata when key ends in -bin ([1d120c7](https://github.com/googleapis/python-error-reporting/commit/1d120c77c73b566796b32cab017a0d4cdfa28713)) -* Remove setup.cfg configuration for creating universal wheels ([#562](https://github.com/googleapis/python-error-reporting/issues/562)) ([0738c03](https://github.com/googleapis/python-error-reporting/commit/0738c03fa4321fd29c0915da2336bf77947367ae)) -* Require proto-plus >= 1.25.0 for Python 3.13 ([#567](https://github.com/googleapis/python-error-reporting/issues/567)) ([d5cd225](https://github.com/googleapis/python-error-reporting/commit/d5cd225fd71d8b54197c4f02c30d32eb8cd24dfa)) - -## [1.11.1](https://github.com/googleapis/python-error-reporting/compare/v1.11.0...v1.11.1) (2024-09-17) - - -### Bug Fixes - -* Allow Protobuf 5.x ([#507](https://github.com/googleapis/python-error-reporting/issues/507)) ([8d33168](https://github.com/googleapis/python-error-reporting/commit/8d3316866c0825911b26f17fd4f703cabbc3c396)) -* Retry and timeout values do not propagate in requests during pagination ([#518](https://github.com/googleapis/python-error-reporting/issues/518)) ([cbe41fd](https://github.com/googleapis/python-error-reporting/commit/cbe41fd1fa4edbb1c574cd2c07dc99d4415c3078)) - - -### Documentation - -* Add summary_overview template ([#496](https://github.com/googleapis/python-error-reporting/issues/496)) ([988def5](https://github.com/googleapis/python-error-reporting/commit/988def551df3f95577519450470a7cbf5f3b6b7d)) -* Removes references as a "global-only" service ([1fef616](https://github.com/googleapis/python-error-reporting/commit/1fef61635e3f9d7297f9fe28d18568cf6c2a0fc1)) -* Updates documentation with regional resource names for multiple requests ([1fef616](https://github.com/googleapis/python-error-reporting/commit/1fef61635e3f9d7297f9fe28d18568cf6c2a0fc1)) - -## [1.11.0](https://github.com/googleapis/python-error-reporting/compare/v1.10.0...v1.11.0) (2024-03-26) - - -### Features - -* Allow users to explicitly configure universe domain ([#475](https://github.com/googleapis/python-error-reporting/issues/475)) ([e4c3454](https://github.com/googleapis/python-error-reporting/commit/e4c3454bd5ba9f452479b0bc956c6ef011766d14)) - -## [1.10.0](https://github.com/googleapis/python-error-reporting/compare/v1.9.2...v1.10.0) (2023-12-10) - - -### Features - -* Add support for Python 3.12 ([#459](https://github.com/googleapis/python-error-reporting/issues/459)) ([36c1b59](https://github.com/googleapis/python-error-reporting/commit/36c1b598b35561e56815ce729884410134c3357d)) -* Use native namespaces instead of pkg_resources ([#463](https://github.com/googleapis/python-error-reporting/issues/463)) ([a63e3f2](https://github.com/googleapis/python-error-reporting/commit/a63e3f25ce5ef0cd0077838cdbb6ceff0f15ce31)) - - -### Bug Fixes - -* Use `retry_async` instead of `retry` in async client ([#462](https://github.com/googleapis/python-error-reporting/issues/462)) ([44c2b14](https://github.com/googleapis/python-error-reporting/commit/44c2b146aec92e272134ebaa6945fe78f98753bd)) - - -### Documentation - -* Minor formatting ([#448](https://github.com/googleapis/python-error-reporting/issues/448)) ([48823d4](https://github.com/googleapis/python-error-reporting/commit/48823d4529fc2a2ac7b6c3f745c3ea5cb0ec9d38)) - -## [1.9.2](https://github.com/googleapis/python-error-reporting/compare/v1.9.1...v1.9.2) (2023-07-04) - - -### Bug Fixes - -* Add async context manager return types ([#434](https://github.com/googleapis/python-error-reporting/issues/434)) ([319fa54](https://github.com/googleapis/python-error-reporting/commit/319fa54a19cb9aca3a079439fd7c6bd2c3163f71)) - -## [1.9.1](https://github.com/googleapis/python-error-reporting/compare/v1.9.0...v1.9.1) (2023-03-23) - - -### Documentation - -* Fix formatting of request arg in docstring ([#422](https://github.com/googleapis/python-error-reporting/issues/422)) ([561dc39](https://github.com/googleapis/python-error-reporting/commit/561dc395302f7989820db79f1c82aad04b7f6f7c)) - -## [1.9.0](https://github.com/googleapis/python-error-reporting/compare/v1.8.2...v1.9.0) (2023-02-28) - - -### Features - -* Enable "rest" transport in Python for services supporting numeric enums ([#418](https://github.com/googleapis/python-error-reporting/issues/418)) ([b2b9eab](https://github.com/googleapis/python-error-reporting/commit/b2b9eab649f413d7ad8a47fd660f9e2bcc32a820)) - -## [1.8.2](https://github.com/googleapis/python-error-reporting/compare/v1.8.1...v1.8.2) (2023-02-04) - - -### Documentation - -* Removed link to the regionalization page ([#411](https://github.com/googleapis/python-error-reporting/issues/411)) ([3a0d82d](https://github.com/googleapis/python-error-reporting/commit/3a0d82db6a425b91430be0ee84fd9c957f39af00)) - -## [1.8.1](https://github.com/googleapis/python-error-reporting/compare/v1.8.0...v1.8.1) (2023-01-20) - - -### Bug Fixes - -* Add context manager return types ([26a0749](https://github.com/googleapis/python-error-reporting/commit/26a074998b0c0a0697ed03086f7e1f6c4b77e35a)) - - -### Documentation - -* Add documentation for enums ([26a0749](https://github.com/googleapis/python-error-reporting/commit/26a074998b0c0a0697ed03086f7e1f6c4b77e35a)) - -## [1.8.0](https://github.com/googleapis/python-error-reporting/compare/v1.7.0...v1.8.0) (2023-01-10) - - -### Features - -* Add support for python 3.11 ([#405](https://github.com/googleapis/python-error-reporting/issues/405)) ([d5e0c4c](https://github.com/googleapis/python-error-reporting/commit/d5e0c4cf0cb40aab80146cad16141217b1998b30)) - -## [1.7.0](https://github.com/googleapis/python-error-reporting/compare/v1.6.3...v1.7.0) (2022-12-15) - - -### Features - -* Add typing to proto.Message based class attributes ([ccaa40f](https://github.com/googleapis/python-error-reporting/commit/ccaa40f1eca7d001cb58cd340189d521e93632ff)) - - -### Bug Fixes - -* Add dict typing for client_options ([ccaa40f](https://github.com/googleapis/python-error-reporting/commit/ccaa40f1eca7d001cb58cd340189d521e93632ff)) -* **deps:** Require google-api-core >=1.34.0, >=2.11.0 ([ccaa40f](https://github.com/googleapis/python-error-reporting/commit/ccaa40f1eca7d001cb58cd340189d521e93632ff)) -* Drop usage of pkg_resources ([ccaa40f](https://github.com/googleapis/python-error-reporting/commit/ccaa40f1eca7d001cb58cd340189d521e93632ff)) -* Fix timeout default values ([ccaa40f](https://github.com/googleapis/python-error-reporting/commit/ccaa40f1eca7d001cb58cd340189d521e93632ff)) - - -### Documentation - -* **samples:** Snippetgen handling of repeated enum field ([ccaa40f](https://github.com/googleapis/python-error-reporting/commit/ccaa40f1eca7d001cb58cd340189d521e93632ff)) -* **samples:** Snippetgen should call await on the operation coroutine before calling result ([ccaa40f](https://github.com/googleapis/python-error-reporting/commit/ccaa40f1eca7d001cb58cd340189d521e93632ff)) - -## [1.6.3](https://github.com/googleapis/python-error-reporting/compare/v1.6.2...v1.6.3) (2022-10-07) - - -### Bug Fixes - -* **deps:** Allow protobuf 3.19.5 ([#391](https://github.com/googleapis/python-error-reporting/issues/391)) ([6a42c05](https://github.com/googleapis/python-error-reporting/commit/6a42c056a7535f4c43d7698525e19df655c91092)) - -## [1.6.2](https://github.com/googleapis/python-error-reporting/compare/v1.6.1...v1.6.2) (2022-10-03) - - -### Bug Fixes - -* **deps:** Require protobuf >= 3.20.2 ([#388](https://github.com/googleapis/python-error-reporting/issues/388)) ([adde212](https://github.com/googleapis/python-error-reporting/commit/adde212c5c37ecbfac9a7ccda9e1fa027c670e52)) - -## [1.6.1](https://github.com/googleapis/python-error-reporting/compare/v1.6.0...v1.6.1) (2022-08-12) - - -### Bug Fixes - -* **deps:** allow protobuf < 5.0.0 ([#366](https://github.com/googleapis/python-error-reporting/issues/366)) ([9535a28](https://github.com/googleapis/python-error-reporting/commit/9535a289a458badf7406688d3e9a77f0e580d0a8)) -* **deps:** require proto-plus >= 1.22.0 ([9535a28](https://github.com/googleapis/python-error-reporting/commit/9535a289a458badf7406688d3e9a77f0e580d0a8)) - -## [1.6.0](https://github.com/googleapis/python-error-reporting/compare/v1.5.3...v1.6.0) (2022-07-14) - - -### Features - -* add audience parameter ([f53a2fa](https://github.com/googleapis/python-error-reporting/commit/f53a2fa49567035a1a3bb94d13444dd65bd104c6)) - - -### Bug Fixes - -* **deps:** require google-api-core>=1.32.0,>=2.8.0 ([#354](https://github.com/googleapis/python-error-reporting/issues/354)) ([f53a2fa](https://github.com/googleapis/python-error-reporting/commit/f53a2fa49567035a1a3bb94d13444dd65bd104c6)) -* require python 3.7+ ([#358](https://github.com/googleapis/python-error-reporting/issues/358)) ([ab0a9ba](https://github.com/googleapis/python-error-reporting/commit/ab0a9bacf9594ce3ff4c521413a20a2995533032)) - -## [1.5.3](https://github.com/googleapis/python-error-reporting/compare/v1.5.2...v1.5.3) (2022-06-07) - - -### Bug Fixes - -* **deps:** require protobuf <4.0.0dev ([#347](https://github.com/googleapis/python-error-reporting/issues/347)) ([ad4c778](https://github.com/googleapis/python-error-reporting/commit/ad4c778e290eb76ea1d62252b5e115ca4c30d42c)) - - -### Documentation - -* fix changelog header to consistent size ([#346](https://github.com/googleapis/python-error-reporting/issues/346)) ([6dc90f7](https://github.com/googleapis/python-error-reporting/commit/6dc90f7e8978c06899c50f1897c160f5e253be79)) - -## [1.5.2](https://github.com/googleapis/python-error-reporting/compare/v1.5.1...v1.5.2) (2022-04-16) - - -### Bug Fixes - -* Reenable staleness bot ([#264](https://github.com/googleapis/python-error-reporting/issues/264)) ([393141a](https://github.com/googleapis/python-error-reporting/commit/393141ac2c661485fdafb8f21fe13a6b2c854d07)) - -## [1.5.1](https://github.com/googleapis/python-error-reporting/compare/v1.5.0...v1.5.1) (2022-03-07) - - -### Bug Fixes - -* **deps:** allow google-cloud-logging <4.0.0dev ([#244](https://github.com/googleapis/python-error-reporting/issues/244)) ([b2f83cf](https://github.com/googleapis/python-error-reporting/commit/b2f83cfb02792d4dfd1d881a07460d90e0ad4eb0)) -* **deps:** require google-api-core>=1.31.5, >=2.3.2 ([#241](https://github.com/googleapis/python-error-reporting/issues/241)) ([af66168](https://github.com/googleapis/python-error-reporting/commit/af66168f3926d63161070bbd3b6c6880155cf07d)) -* **deps:** require proto-plus>=1.15.0 ([af66168](https://github.com/googleapis/python-error-reporting/commit/af66168f3926d63161070bbd3b6c6880155cf07d)) - -## [1.5.0](https://github.com/googleapis/python-error-reporting/compare/v1.4.1...v1.5.0) (2022-02-16) - - -### Features - -* add api key support ([#221](https://github.com/googleapis/python-error-reporting/issues/221)) ([b207f2c](https://github.com/googleapis/python-error-reporting/commit/b207f2cec4f5f3196e775ed35cd429f34f9c0bd1)) - - -### Bug Fixes - -* resolve DuplicateCredentialArgs error when using credentials_file ([f0afcae](https://github.com/googleapis/python-error-reporting/commit/f0afcae54c834872d1e40d1f5c948c1e0c299b85)) - -## [1.4.1](https://www.github.com/googleapis/python-error-reporting/compare/v1.4.0...v1.4.1) (2021-11-01) - - -### Bug Fixes - -* **deps:** drop packaging dependency ([31e3d6b](https://www.github.com/googleapis/python-error-reporting/commit/31e3d6b269139831e914165a316b450c01bc6c0d)) -* **deps:** require google-api-core >= 1.28.0 ([31e3d6b](https://www.github.com/googleapis/python-error-reporting/commit/31e3d6b269139831e914165a316b450c01bc6c0d)) - - -### Documentation - -* list oneofs in docstring ([31e3d6b](https://www.github.com/googleapis/python-error-reporting/commit/31e3d6b269139831e914165a316b450c01bc6c0d)) - -## [1.4.0](https://www.github.com/googleapis/python-error-reporting/compare/v1.3.0...v1.4.0) (2021-10-14) - - -### Features - -* add support for python 3.10 ([#192](https://www.github.com/googleapis/python-error-reporting/issues/192)) ([76cc041](https://www.github.com/googleapis/python-error-reporting/commit/76cc041c367d05a361c2fce355340e01bae116ed)) - -## [1.3.0](https://www.github.com/googleapis/python-error-reporting/compare/v1.2.3...v1.3.0) (2021-10-11) - - -### Features - -* add context manager support in client ([#187](https://www.github.com/googleapis/python-error-reporting/issues/187)) ([a4e2cd4](https://www.github.com/googleapis/python-error-reporting/commit/a4e2cd4654ae6b3f785727e279ce362798368598)) - - -### Bug Fixes - -* exception thrown when grpc is disabled ([#190](https://www.github.com/googleapis/python-error-reporting/issues/190)) ([929e293](https://www.github.com/googleapis/python-error-reporting/commit/929e293a479dea3059bfca152b93d7740348fc39)) -* improper types in pagers generation ([18c93a9](https://www.github.com/googleapis/python-error-reporting/commit/18c93a99a967b6d86e7409f4e26ff56f1c9788de)) - -## [1.2.3](https://www.github.com/googleapis/python-error-reporting/compare/v1.2.2...v1.2.3) (2021-09-24) - - -### Bug Fixes - -* add 'dict' annotation type to 'request' ([253a66f](https://www.github.com/googleapis/python-error-reporting/commit/253a66f5f606f722bf5401cdd678989b9d2baa98)) - -## [1.2.2](https://www.github.com/googleapis/python-error-reporting/compare/v1.2.1...v1.2.2) (2021-07-28) - - -### Bug Fixes - -* enable self signed jwt for grpc ([#156](https://www.github.com/googleapis/python-error-reporting/issues/156)) ([f9656c8](https://www.github.com/googleapis/python-error-reporting/commit/f9656c81db2f29ba4ac9ba4a5304004cd725ca5c)) - - -### Documentation - -* add Samples section to CONTRIBUTING.rst ([#151](https://www.github.com/googleapis/python-error-reporting/issues/151)) ([8f11190](https://www.github.com/googleapis/python-error-reporting/commit/8f11190661e62165bd1c4a30b40797ef31abed33)) - - -### Miscellaneous Chores - -* release as 1.2.2 ([#157](https://www.github.com/googleapis/python-error-reporting/issues/157)) ([ea26377](https://www.github.com/googleapis/python-error-reporting/commit/ea2637721efac36b122edc499da08c12ae894d28)) - -## [1.2.1](https://www.github.com/googleapis/python-error-reporting/compare/v1.2.0...v1.2.1) (2021-07-20) - - -### Bug Fixes - -* **deps:** pin 'google-{api,cloud}-core', 'google-auth' to allow 2.x versions ([#150](https://www.github.com/googleapis/python-error-reporting/issues/150)) ([1c87673](https://www.github.com/googleapis/python-error-reporting/commit/1c876738b0bdca1b2bd65d78fa541846b0474cfa)) - -## [1.2.0](https://www.github.com/googleapis/python-error-reporting/compare/v1.1.2...v1.2.0) (2021-07-01) - - -### Features - -* add always_use_jwt_access ([#140](https://www.github.com/googleapis/python-error-reporting/issues/140)) ([2f8f790](https://www.github.com/googleapis/python-error-reporting/commit/2f8f790dd70646848afd5e5209a147b01c6f388b)) - - -### Bug Fixes - -* **deps:** add packaging requirement ([#124](https://www.github.com/googleapis/python-error-reporting/issues/124)) ([ed36389](https://www.github.com/googleapis/python-error-reporting/commit/ed3638946f8829c4d2b379785e38cc2a2228c688)) -* **deps:** widen version range on google-cloud-logging ([#133](https://www.github.com/googleapis/python-error-reporting/issues/133)) ([c5e87bb](https://www.github.com/googleapis/python-error-reporting/commit/c5e87bb8c177688833ca9524daa4e6229875627d)) -* disable always_use_jwt_access ([8aff323](https://www.github.com/googleapis/python-error-reporting/commit/8aff32330ebf544cc043bec0003140d61df7e7a1)) -* disable always_use_jwt_access ([#144](https://www.github.com/googleapis/python-error-reporting/issues/144)) ([8aff323](https://www.github.com/googleapis/python-error-reporting/commit/8aff32330ebf544cc043bec0003140d61df7e7a1)) - - -### Documentation - -* omit mention of Python 2.7 in 'CONTRIBUTING.rst' ([#1127](https://www.github.com/googleapis/python-error-reporting/issues/1127)) ([#137](https://www.github.com/googleapis/python-error-reporting/issues/137)) ([0ca7d43](https://www.github.com/googleapis/python-error-reporting/commit/0ca7d4385de86e7ff462322807a717345774c017)) - -## [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) - - -### Bug Fixes - -* remove gRPC send/recv limit; add enums to `types/__init__.py` ([#57](https://www.github.com/googleapis/python-error-reporting/issues/57)) ([e23e5ba](https://www.github.com/googleapis/python-error-reporting/commit/e23e5ba7eba4482735d5f4897210a1ebb81bfb8a)) - -## [1.1.0](https://www.github.com/googleapis/python-error-reporting/compare/v1.0.0...v1.1.0) (2020-12-01) - - -### Features - -* add common resource path helpers; expose client transport as property ([#37](https://www.github.com/googleapis/python-error-reporting/issues/37)) ([bc92bc2](https://www.github.com/googleapis/python-error-reporting/commit/bc92bc2cfa549200bf8fa87cf2f6d81ded77486c)) - - -### Bug Fixes - -* changed import path for logging client ([#43](https://www.github.com/googleapis/python-error-reporting/issues/43)) ([a09449d](https://www.github.com/googleapis/python-error-reporting/commit/a09449def35077beb85782c34a61c8f172c2f018)) - - -### Documentation - -* removed stackdriver branding ([#44](https://www.github.com/googleapis/python-error-reporting/issues/44)) ([5eea8c4](https://www.github.com/googleapis/python-error-reporting/commit/5eea8c4f533a32d2b81b1b69e48d3bb47f1bc5b4)) - -## [1.0.0](https://www.github.com/googleapis/python-error-reporting/compare/v0.34.0...v1.0.0) (2020-08-28) - - -### ⚠ BREAKING CHANGES - -* migrate to use microgen (#23) - -### Features - -* migrate to use microgen ([#23](https://www.github.com/googleapis/python-error-reporting/issues/23)) ([cb41e3a](https://www.github.com/googleapis/python-error-reporting/commit/cb41e3a1003cb4ef4e32efc8b5c5b5ba7d670f7d)) - - -### Documentation - -* add multiprocessing note ([#13](https://www.github.com/googleapis/python-error-reporting/issues/13)) ([840d67c](https://www.github.com/googleapis/python-error-reporting/commit/840d67c09502ae99ce4771c66bde1cefb961a367)) - -## [0.34.0](https://www.github.com/googleapis/python-error-reporting/compare/v0.33.0...v0.34.0) (2020-05-03) - - -### Features - -* set release_status to beta ([#5](https://www.github.com/googleapis/python-error-reporting/issues/5)) ([e9361c5](https://www.github.com/googleapis/python-error-reporting/commit/e9361c5e0f427a4796974fd4a3da506324220e9e)) - -## 0.33.0 - -10-22-2019 12:10 PDT - -### New Features -- Add `client_options` to constructor ([#9152](https://github.com/googleapis/google-cloud-python/pull/9152)) - -### Dependencies -- Pin `google-cloud-logging >= 1.14.0, < 2.0.0dev`. ([#9476](https://github.com/googleapis/google-cloud-python/pull/9476)) - -### Documentation -- Remove references to the old authentication credentials. ([#9456](https://github.com/googleapis/google-cloud-python/pull/9456)) -- Fix intersphinx reference to requests. ([#9294](https://github.com/googleapis/google-cloud-python/pull/9294)) -- Remove CI for `gh-pages`, use googleapis.dev for `api_core` refs. ([#9085](https://github.com/googleapis/google-cloud-python/pull/9085)) - -### Internal / Testing Changes -- Harden `test_report_exception` systest by increasing `max_tries`. ([#9396](https://github.com/googleapis/google-cloud-python/pull/9396)) - -## 0.32.1 - -08-23-2019 10:12 PDT - -### Implementation Changes -- Remove send/recv msg size limit (via synth). ([#8954](https://github.com/googleapis/google-cloud-python/pull/8954)) - -### Documentation -- Fix documentation links for iam and error-reporting. ([#9073](https://github.com/googleapis/google-cloud-python/pull/9073)) -- Remove compatability badges from READMEs. ([#9035](https://github.com/googleapis/google-cloud-python/pull/9035)) -- Update intersphinx mapping for requests. ([#8805](https://github.com/googleapis/google-cloud-python/pull/8805)) - -## 0.32.0 - -07-24-2019 16:17 PDT - - -### Implementation Changes -- Allow kwargs to be passed to create_channel (via synth). ([#8389](https://github.com/googleapis/google-cloud-python/pull/8389)) -- Fix typo in non-gRPC import. ([#8028](https://github.com/googleapis/google-cloud-python/pull/8028)) - -### New Features -- Add 'client_options' support, update list method docstrings (via synth). ([#8508](https://github.com/googleapis/google-cloud-python/pull/8508)) - -### Documentation -- Fix docs navigation issues. ([#8723](https://github.com/googleapis/google-cloud-python/pull/8723)) -- Link to googleapis.dev documentation in READMEs. ([#8705](https://github.com/googleapis/google-cloud-python/pull/8705)) -- Add compatibility check badges to READMEs. ([#8288](https://github.com/googleapis/google-cloud-python/pull/8288)) -- Fix mistake in documentation ([#8271](https://github.com/googleapis/google-cloud-python/pull/8271)) - -### Internal / Testing Changes -- Pin black version (via synth). ([#8582](https://github.com/googleapis/google-cloud-python/pull/8582)) -- Add docs job to publish to googleapis.dev. ([#8464](https://github.com/googleapis/google-cloud-python/pull/8464)) -- Declare encoding as utf-8 in pb2 files (via synth). ([#8351](https://github.com/googleapis/google-cloud-python/pull/8351)) -- Add disclaimer to auto-generated template files (via synth). ([#8313](https://github.com/googleapis/google-cloud-python/pull/8313)) -- Suppress checking 'cov-fail-under' in nox default session (via synth). ([#8240](https://github.com/googleapis/google-cloud-python/pull/8240)) -- Blacken noxfile.py, setup.py (via synth). ([#8122](https://github.com/googleapis/google-cloud-python/pull/8122)) -- Add empty lines (via synth). ([#8057](https://github.com/googleapis/google-cloud-python/pull/8057)) - -## 0.31.0 - -05-17-2019 08:23 PDT - -### Implementation Changes -- Add routing header to method metadata (via synth). ([#7594](https://github.com/googleapis/google-cloud-python/pull/7594)) -- Remove classifier for Python 3.4 for end-of-life. ([#7535](https://github.com/googleapis/google-cloud-python/pull/7535)) - -### New Features -- Add `client_info` support to Client. ([#7903](https://github.com/googleapis/google-cloud-python/pull/7903)) - -### Dependencies -- Pin `google-cloud-logging >= 1.11.0`. ([#8015](https://github.com/googleapis/google-cloud-python/pull/8015)) - -### Documentation -- Update client library documentation URLs. ([#7307](https://github.com/googleapis/google-cloud-python/pull/7307)) - -### Internal / Testing Changes -- Add nox session `docs` (via synth). ([#7770](https://github.com/googleapis/google-cloud-python/pull/7770)) -- Fix docstring replace in synth ([#7458](https://github.com/googleapis/google-cloud-python/pull/7458)) -- Copy lintified proto files (via synth). ([#7447](https://github.com/googleapis/google-cloud-python/pull/7447)) -- Add clarifying comment to blacken nox target (via synth). ([#7391](https://github.com/googleapis/google-cloud-python/pull/7391)) -- Add protos as an artifact to library ([#7205](https://github.com/googleapis/google-cloud-python/pull/7205)) -- Update copyright headers. ([#7144](https://github.com/googleapis/google-cloud-python/pull/7144)) -- Protoc-generated serialization update. ([#7082](https://github.com/googleapis/google-cloud-python/pull/7082)) -- Pick up stub docstring fix in GAPIC generator. ([#6970](https://github.com/googleapis/google-cloud-python/pull/6970)) -- Fix formatting ([#7002](https://github.com/googleapis/google-cloud-python/pull/7002)) - -## 0.30.1 - -12-17-2018 18:17 PST - - -### Implementation Changes -- Pick up fixes to GAPIC generator. ([#6522](https://github.com/googleapis/google-cloud-python/pull/6522)) -- Fix `client_info` bug, update docstrings via synth. ([#6442](https://github.com/googleapis/google-cloud-python/pull/6442)) - -### Documentation -- Document Python 2 deprecation ([#6910](https://github.com/googleapis/google-cloud-python/pull/6910)) -- Fix [#6321](https://github.com/googleapis/google-cloud-python/pull/6321) Update README service links in quickstart guides. ([#6322](https://github.com/googleapis/google-cloud-python/pull/6322)) -- Prep docs for repo split. ([#6155](https://github.com/googleapis/google-cloud-python/pull/6155)) -- Replace links to `/stable/` with `/latest/`. ([#5901](https://github.com/googleapis/google-cloud-python/pull/5901)) - -### Internal / Testing Changes -- Update noxfile. -- Blacken all gen'd libs ([#6792](https://github.com/googleapis/google-cloud-python/pull/6792)) -- Omit local deps ([#6701](https://github.com/googleapis/google-cloud-python/pull/6701)) -- Run black at end of synth.py ([#6698](https://github.com/googleapis/google-cloud-python/pull/6698)) -- Run Black on Generated libraries ([#6666](https://github.com/googleapis/google-cloud-python/pull/6666)) -- Add templates for flake8, coveragerc, noxfile, and black. ([#6642](https://github.com/googleapis/google-cloud-python/pull/6642)) -- Add synth metadata. ([#6566](https://github.com/googleapis/google-cloud-python/pull/6566)) -- Use new Nox ([#6175](https://github.com/googleapis/google-cloud-python/pull/6175)) -- Add 'synth.py'. ([#6082](https://github.com/googleapis/google-cloud-python/pull/6082)) -- Use Nox inplace installs ([#5865](https://github.com/googleapis/google-cloud-python/pull/5865)) - -## 0.30.0 - -### Implementation Changes -- Make dependency on logging less restrictive in error_reporting (#5345) - -### Internal / Testing Changes -- Modify system tests to use prerelease versions of grpcio (#5304) -- Add Test runs for Python 3.7 and remove 3.4 (#5295) -- Fix bad trove classifier - -## 0.29.1 - -### Dependencies - -- Update dependency range for api-core to include v1.0.0 releases (#4944) -- Fix missing extra in api-core dependency (#4764) - -### Testing and internal changes - -- Install local dependencies when running lint (#4936) -- Re-enable lint for tests, remove usage of pylint (#4921) -- Normalize all setup.py files (#4909) - -## 0.29.0 - -### Breaking changes - -- The underlying autogenerated client library was re-generated to pick up new - features and resolve bugs, this may change the exceptions raised from various - methods. (#4695) - -## 0.28.0 - -### Documentation - -- Added link to "Python Development Environment Setup Guide" in - project README (#4187, h/t to @michaelawyu) - -### Dependencies - -- Upgrading to `google-cloud-core >= 0.28.0` and adding dependency - on `google-api-core` (#4221, #4280) -- Upgrading to `google-cloud-logging >= 1.4.0` (#4296) - -PyPI: https://pypi.org/project/google-cloud-error-reporting/0.28.0/ diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 039f4368..00000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,95 +0,0 @@ - -# Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of -experience, education, socio-economic status, nationality, personal appearance, -race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, or to ban temporarily or permanently any -contributor for other behaviors that they deem inappropriate, threatening, -offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -This Code of Conduct also applies outside the project spaces when the Project -Steward has a reasonable belief that an individual's behavior may have a -negative impact on the project or its community. - -## Conflict Resolution - -We do not believe that all conflict is bad; healthy debate and disagreement -often yield positive results. However, it is never okay to be disrespectful or -to engage in behavior that violates the project’s code of conduct. - -If you see someone violating the code of conduct, you are encouraged to address -the behavior directly with those involved. Many issues can be resolved quickly -and easily, and this gives people more control over the outcome of their -dispute. If you are unable to resolve the matter for any reason, or if the -behavior is threatening or harassing, report it. We are dedicated to providing -an environment where participants feel welcome and safe. - - -Reports should be directed to *googleapis-stewards@google.com*, the -Project Steward(s) for *Google Cloud Client Libraries*. It is the Project Steward’s duty to -receive and address reported violations of the code of conduct. They will then -work with a committee consisting of representatives from the Open Source -Programs Office and the Google Open Source Strategy team. If for any reason you -are uncomfortable reaching out to the Project Steward, please email -opensource@google.com. - -We will investigate every complaint, but you may not receive a direct response. -We will use our discretion in determining when and how to follow up on reported -incidents, which may range from not taking action to permanent expulsion from -the project and project-sponsored spaces. We will notify the accused of the -report and provide them an opportunity to discuss it before any action is taken. -The identity of the reporter will be omitted from the details of the report -supplied to the accused. In potentially harmful situations, such as ongoing -harassment or threats to anyone's safety, we may take action without notice. - -## Attribution - -This Code of Conduct is adapted from the Contributor Covenant, version 1.4, -available at -https://www.contributor-covenant.org/version/1/4/code-of-conduct.html \ No newline at end of file diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst deleted file mode 100644 index 222b6e01..00000000 --- a/CONTRIBUTING.rst +++ /dev/null @@ -1,287 +0,0 @@ -.. Generated by synthtool. DO NOT EDIT! -############ -Contributing -############ - -#. **Please sign one of the contributor license agreements below.** -#. Fork the repo, develop and test your code changes, add docs. -#. Make sure that your commit messages clearly describe the changes. -#. Send a pull request. (Please Read: `Faster Pull Request Reviews`_) - -.. _Faster Pull Request Reviews: https://github.com/kubernetes/community/blob/master/contributors/guide/pull-requests.md#best-practices-for-faster-reviews - -.. contents:: Here are some guidelines for hacking on the Google Cloud Client libraries. - -*************** -Adding Features -*************** - -In order to add a feature: - -- The feature must be documented in both the API and narrative - documentation. - -- The feature must work fully on the following CPython versions: - 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13 and 3.14 on both UNIX and Windows. - -- The feature must not add unnecessary dependencies (where - "unnecessary" is of course subjective, but new dependencies should - be discussed). - -**************************** -Using a Development Checkout -**************************** - -You'll have to create a development environment using a Git checkout: - -- While logged into your GitHub account, navigate to the - ``python-error-reporting`` `repo`_ on GitHub. - -- Fork and clone the ``python-error-reporting`` repository to your GitHub account by - clicking the "Fork" button. - -- Clone your fork of ``python-error-reporting`` from your GitHub account to your local - computer, substituting your account username and specifying the destination - as ``hack-on-python-error-reporting``. E.g.:: - - $ cd ${HOME} - $ git clone git@github.com:USERNAME/python-error-reporting.git hack-on-python-error-reporting - $ cd hack-on-python-error-reporting - # Configure remotes such that you can pull changes from the googleapis/python-error-reporting - # repository into your local repository. - $ git remote add upstream git@github.com:googleapis/python-error-reporting.git - # fetch and merge changes from upstream into main - $ git fetch upstream - $ git merge upstream/main - -Now your local repo is set up such that you will push changes to your GitHub -repo, from which you can submit a pull request. - -To work on the codebase and run the tests, we recommend using ``nox``, -but you can also use a ``virtualenv`` of your own creation. - -.. _repo: https://github.com/googleapis/python-error-reporting - -Using ``nox`` -============= - -We use `nox `__ to instrument our tests. - -- To test your changes, run unit tests with ``nox``:: - $ nox -s unit - -- To run a single unit test:: - - $ nox -s unit-3.13 -- -k - - - .. note:: - - The unit tests and system tests are described in the - ``noxfile.py`` files in each directory. - -.. nox: https://pypi.org/project/nox/ - -***************************************** -I'm getting weird errors... Can you help? -***************************************** - -If the error mentions ``Python.h`` not being found, -install ``python-dev`` and try again. -On Debian/Ubuntu:: - - $ sudo apt-get install python-dev - -************ -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 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:: - - $ nox -s lint - -- In order to make ``nox -s lint`` run faster, you can set some environment - variables:: - - export GOOGLE_CLOUD_TESTING_REMOTE="upstream" - export GOOGLE_CLOUD_TESTING_BRANCH="main" - - By doing this, you are specifying the location of the most up-to-date - version of ``python-error-reporting``. The - remote name ``upstream`` should point to the official ``googleapis`` - checkout and the branch should be the default branch on that remote (``main``). - -- This repository contains configuration for the - `pre-commit `__ tool, which automates checking - our linters during a commit. If you have it installed on your ``$PATH``, - you can enable enforcing those checks via: - -.. code-block:: bash - - $ pre-commit install - pre-commit installed at .git/hooks/pre-commit - -Exceptions to PEP8: - -- Many unit tests use a helper method, ``_call_fut`` ("FUT" is short for - "Function-Under-Test"), which is PEP8-incompliant, but more readable. - Some also use a local variable, ``MUT`` (short for "Module-Under-Test"). - -******************** -Running System Tests -******************** - -- To run system tests, you can execute:: - - # Run all system tests - $ nox -s system - - # Run a single system test - $ nox -s system-3.14 -- -k - - - .. note:: - - System tests are only configured to run under Python 3.14. - For expediency, we do not run them in older versions of Python 3. - - This alone will not run the tests. You'll need to change some local - auth settings and change some configuration in your project to - run all the tests. - -- System tests will be run against an actual project. You should use local credentials from gcloud when possible. See `Best practices for application authentication `__. Some tests require a service account. For those tests see `Authenticating as a service account `__. - -************* -Test Coverage -************* - -- The codebase *must* have 100% test statement coverage after each commit. - You can test coverage via ``nox -s cover``. - -****************************************************** -Documentation Coverage and Building HTML Documentation -****************************************************** - -If you fix a bug, and the bug requires an API or behavior modification, all -documentation in this package which references that API or behavior must be -changed to reflect the bug fix, ideally in the same commit that fixes the bug -or adds the feature. - -Build the docs via: - - $ nox -s docs - -************************* -Samples and code snippets -************************* - -Code samples and snippets live in the `samples/` catalogue. Feel free to -provide more examples, but make sure to write tests for those examples. -Each folder containing example code requires its own `noxfile.py` script -which automates testing. If you decide to create a new folder, you can -base it on the `samples/snippets` folder (providing `noxfile.py` and -the requirements files). - -The tests will run against a real Google Cloud Project, so you should -configure them just like the System Tests. - -- To run sample tests, you can execute:: - - # Run all tests in a folder - $ cd samples/snippets - $ nox -s py-3.14 - - # Run a single sample test - $ cd samples/snippets - $ nox -s py-3.14 -- -k - -******************************************** -Note About ``README`` as it pertains to PyPI -******************************************** - -The `description on PyPI`_ for the project comes directly from the -``README``. Due to the reStructuredText (``rst``) parser used by -PyPI, relative links which will work on GitHub (e.g. ``CONTRIBUTING.rst`` -instead of -``https://github.com/googleapis/python-error-reporting/blob/main/CONTRIBUTING.rst``) -may cause problems creating links or rendering the description. - -.. _description on PyPI: https://pypi.org/project/google-cloud-error-reporting - - -************************* -Supported Python Versions -************************* - -We support: - -- `Python 3.7`_ -- `Python 3.8`_ -- `Python 3.9`_ -- `Python 3.10`_ -- `Python 3.11`_ -- `Python 3.12`_ -- `Python 3.13`_ -- `Python 3.14`_ - -.. _Python 3.7: https://docs.python.org/3.7/ -.. _Python 3.8: https://docs.python.org/3.8/ -.. _Python 3.9: https://docs.python.org/3.9/ -.. _Python 3.10: https://docs.python.org/3.10/ -.. _Python 3.11: https://docs.python.org/3.11/ -.. _Python 3.12: https://docs.python.org/3.12/ -.. _Python 3.13: https://docs.python.org/3.13/ -.. _Python 3.14: https://docs.python.org/3.14/ - - -Supported versions can be found in our ``noxfile.py`` `config`_. - -.. _config: https://github.com/googleapis/python-error-reporting/blob/main/noxfile.py - - -We also explicitly decided to support Python 3 beginning with version 3.7. -Reasons for this include: - -- Encouraging use of newest versions of Python 3 -- Taking the lead of `prominent`_ open-source `projects`_ -- `Unicode literal support`_ which allows for a cleaner codebase that - works in both Python 2 and Python 3 - -.. _prominent: https://docs.djangoproject.com/en/1.9/faq/install/#what-python-version-can-i-use-with-django -.. _projects: http://flask.pocoo.org/docs/0.10/python3/ -.. _Unicode literal support: https://www.python.org/dev/peps/pep-0414/ - -********** -Versioning -********** - -This library follows `Semantic Versioning`_. - -.. _Semantic Versioning: http://semver.org/ - -Some packages are currently in major version zero (``0.y.z``), which means that -anything may change at any time and the public API should not be considered -stable. - -****************************** -Contributor License Agreements -****************************** - -Before we can accept your pull requests you'll need to sign a Contributor -License Agreement (CLA): - -- **If you are an individual writing original source code** and **you own the - intellectual property**, then you'll need to sign an - `individual CLA `__. -- **If you work for a company that wants to allow you to contribute your work**, - then you'll need to sign a - `corporate CLA `__. - -You can sign these electronically (just scroll to the bottom). After that, -we'll be able to accept your pull requests. diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index dae249ec..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -include README.rst LICENSE -recursive-include google *.py *.pyi *.json *.proto py.typed -recursive-include tests * -global-exclude *.py[co] -global-exclude __pycache__ diff --git a/README.rst b/README.rst index 7a401641..f22659cd 100644 --- a/README.rst +++ b/README.rst @@ -1,3 +1,8 @@ +:**NOTE**: **This github repository is archived. The repository contents and history have moved to** `google-cloud-python`_. + +.. _google-cloud-python: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-error-reporting + + Python Client for Error Reporting API ===================================== diff --git a/devtools-clouderrorreporting-v1beta1-py.tar.gz b/devtools-clouderrorreporting-v1beta1-py.tar.gz deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/README.rst b/docs/README.rst deleted file mode 100644 index 7a401641..00000000 --- a/docs/README.rst +++ /dev/null @@ -1,197 +0,0 @@ -Python Client for Error Reporting API -===================================== - -|preview| |pypi| |versions| - -`Error Reporting API`_: counts, analyzes and aggregates the crashes in your running cloud services. A centralized error management interface displays the results with sorting and filtering capabilities. A dedicated view shows the error details: time chart, occurrences, affected user count, first and last seen dates and a cleaned exception stack trace. Opt-in to receive email and mobile alerts on new errors. - -- `Client Library Documentation`_ -- `Product Documentation`_ - -.. |preview| image:: https://img.shields.io/badge/support-preview-orange.svg - :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels -.. |pypi| image:: https://img.shields.io/pypi/v/google-cloud-error-reporting.svg - :target: https://pypi.org/project/google-cloud-error-reporting/ -.. |versions| image:: https://img.shields.io/pypi/pyversions/google-cloud-error-reporting.svg - :target: https://pypi.org/project/google-cloud-error-reporting/ -.. _Error Reporting API: https://cloud.google.com/error-reporting -.. _Client Library Documentation: https://cloud.google.com/python/docs/reference/clouderrorreporting/latest/summary_overview -.. _Product Documentation: https://cloud.google.com/error-reporting - -Quick Start ------------ - -In order to use this library, you first need to go through the following steps: - -1. `Select or create a Cloud Platform project.`_ -2. `Enable billing for your project.`_ -3. `Enable the Error Reporting API.`_ -4. `Set up Authentication.`_ - -.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project -.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project -.. _Enable the Error Reporting API.: https://cloud.google.com/error-reporting -.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html - -Installation -~~~~~~~~~~~~ - -Install this library in a virtual environment using `venv`_. `venv`_ is a tool that -creates isolated Python environments. These isolated environments can have separate -versions of Python packages, which allows you to isolate one project's dependencies -from the dependencies of other projects. - -With `venv`_, it's possible to install this library without needing system -install permissions, and without clashing with the installed system -dependencies. - -.. _`venv`: https://docs.python.org/3/library/venv.html - - -Code samples and snippets -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Code samples and snippets live in the `samples/`_ folder. - -.. _samples/: https://github.com/googleapis/python-error-reporting/tree/main/samples - - -Supported Python Versions -^^^^^^^^^^^^^^^^^^^^^^^^^ -Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of -Python. - -Python >= 3.7, including 3.14 - -.. _active: https://devguide.python.org/devcycle/#in-development-main-branch -.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches - -Unsupported Python Versions -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Python <= 3.6 - -If you are using an `end-of-life`_ -version of Python, we recommend that you update as soon as possible to an actively supported version. - -.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches - -Mac/Linux -^^^^^^^^^ - -.. code-block:: console - - python3 -m venv - source /bin/activate - pip install google-cloud-error-reporting - - -Windows -^^^^^^^ - -.. code-block:: console - - py -m venv - .\\Scripts\activate - pip install google-cloud-error-reporting - -Next Steps -~~~~~~~~~~ - -- Read the `Client Library Documentation`_ for Error Reporting API - to see other available methods on the client. -- Read the `Error Reporting API Product documentation`_ to learn - more about the product and see How-to Guides. -- View this `README`_ to see the full list of Cloud - APIs that we cover. - -.. _Error Reporting API Product documentation: https://cloud.google.com/error-reporting -.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst - -Logging -------- - -This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. -Note the following: - -#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. -#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. -#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. - -Simple, environment-based configuration -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google -logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged -messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging -event. - -A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. - -- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. -- Invalid logging scopes: :code:`foo`, :code:`123`, etc. - -**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. - -Environment-Based Examples -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Enabling the default handler for all Google-based loggers - -.. code-block:: console - - export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google - -- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): - -.. code-block:: console - - export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 - - -Advanced, code-based configuration -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can also configure a valid logging scope using Python's standard `logging` mechanism. - -Code-Based Examples -^^^^^^^^^^^^^^^^^^^ - -- Configuring a handler for all Google-based loggers - -.. code-block:: python - - import logging - - from google.cloud import library_v1 - - base_logger = logging.getLogger("google") - base_logger.addHandler(logging.StreamHandler()) - base_logger.setLevel(logging.DEBUG) - -- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): - -.. code-block:: python - - import logging - - from google.cloud import library_v1 - - base_logger = logging.getLogger("google.cloud.library_v1") - base_logger.addHandler(logging.StreamHandler()) - base_logger.setLevel(logging.DEBUG) - -Logging details -~~~~~~~~~~~~~~~ - -#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root - logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set - :code:`logging.getLogger("google").propagate = True` in your code. -#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for - one library, but decide you need to also set up environment-based logging configuration for another library. - - #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual - if the code -based configuration gets applied first. - -#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get - executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. - (This is the reason for 2.i. above.) diff --git a/docs/_static/custom.css b/docs/_static/custom.css deleted file mode 100644 index b0a29546..00000000 --- a/docs/_static/custom.css +++ /dev/null @@ -1,20 +0,0 @@ -div#python2-eol { - border-color: red; - border-width: medium; -} - -/* Ensure minimum width for 'Parameters' / 'Returns' column */ -dl.field-list > dt { - min-width: 100px -} - -/* Insert space between methods for readability */ -dl.method { - padding-top: 10px; - padding-bottom: 10px -} - -/* Insert empty space between classes */ -dl.class { - padding-bottom: 50px -} diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html deleted file mode 100644 index 95e9c77f..00000000 --- a/docs/_templates/layout.html +++ /dev/null @@ -1,50 +0,0 @@ - -{% extends "!layout.html" %} -{%- block content %} -{%- if theme_fixed_sidebar|lower == 'true' %} -
- {{ sidebar() }} - {%- block document %} -
- {%- if render_sidebar %} -
- {%- endif %} - - {%- block relbar_top %} - {%- if theme_show_relbar_top|tobool %} - - {%- endif %} - {% endblock %} - -
-
- As of January 1, 2020 this library no longer supports Python 2 on the latest released version. - Library versions released prior to that date will continue to be available. For more information please - visit Python 2 support on Google Cloud. -
- {% block body %} {% endblock %} -
- - {%- block relbar_bottom %} - {%- if theme_show_relbar_bottom|tobool %} - - {%- endif %} - {% endblock %} - - {%- if render_sidebar %} -
- {%- endif %} -
- {%- endblock %} -
-
-{%- else %} -{{ super() }} -{%- endif %} -{%- endblock %} diff --git a/docs/changelog.md b/docs/changelog.md deleted file mode 120000 index 04c99a55..00000000 --- a/docs/changelog.md +++ /dev/null @@ -1 +0,0 @@ -../CHANGELOG.md \ No newline at end of file diff --git a/docs/client.rst b/docs/client.rst deleted file mode 100644 index 93fcff3b..00000000 --- a/docs/client.rst +++ /dev/null @@ -1,6 +0,0 @@ -Error Reporting Client -======================= - -.. automodule:: google.cloud.error_reporting.client - :members: - :show-inheritance: diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index ef62ba33..00000000 --- a/docs/conf.py +++ /dev/null @@ -1,418 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -## -# google-cloud-error-reporting documentation build configuration file -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import logging -import os -import shlex -import sys -import logging -from typing import Any - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath("..")) - -# For plugins that can not read conf.py. -# See also: https://github.com/docascode/sphinx-docfx-yaml/issues/85 -sys.path.insert(0, os.path.abspath(".")) - -__version__ = "" - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = "4.5.0" - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "sphinx.ext.autodoc", - "sphinx.ext.autosummary", - "sphinx.ext.intersphinx", - "sphinx.ext.coverage", - "sphinx.ext.doctest", - "sphinx.ext.napoleon", - "sphinx.ext.todo", - "sphinx.ext.viewcode", - "recommonmark", -] - -# autodoc/autosummary flags -autoclass_content = "both" -autodoc_default_options = {"members": True} -autosummary_generate = True - - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] -source_suffix = [".rst", ".md"] - -# The encoding of source files. -# source_encoding = 'utf-8-sig' - -# The root toctree document. -root_doc = "index" - -# General information about the project. -project = "google-cloud-error-reporting" -copyright = "2025, Google, LLC" -author = "Google APIs" - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The full version, including alpha/beta/rc tags. -release = __version__ -# The short X.Y version. -version = ".".join(release.split(".")[0:2]) - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# today = '' -# Else, today_fmt is used as the format for a strftime call. -# today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [ - "_build", - "**/.nox/**/*", - "samples/AUTHORING_GUIDE.md", - "samples/CONTRIBUTING.md", - "samples/snippets/README.rst", -] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -# keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = "alabaster" - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -html_theme_options = { - "description": "Google Cloud Client Libraries for google-cloud-error-reporting", - "github_user": "googleapis", - "github_repo": "google-cloud-python", - "github_banner": True, - "font_family": "'Roboto', Georgia, sans", - "head_font_family": "'Roboto', Georgia, serif", - "code_font_family": "'Roboto Mono', 'Consolas', monospace", -} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -# html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -# html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# html_additional_pages = {} - -# If false, no module index is generated. -# html_domain_indices = True - -# If false, no index is generated. -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -# html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -# html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -# html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = "google-cloud-error-reporting-doc" - -# -- Options for warnings ------------------------------------------------------ - - -suppress_warnings = [ - # Temporarily suppress this to avoid "more than one target found for - # cross-reference" warning, which are intractable for us to avoid while in - # a mono-repo. - # See https://github.com/sphinx-doc/sphinx/blob - # /2a65ffeef5c107c19084fabdd706cdff3f52d93c/sphinx/domains/python.py#L843 - "ref.python" -] - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - # 'preamble': '', - # Latex figure (float) alignment - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ( - root_doc, - "google-cloud-error-reporting.tex", - "google-cloud-error-reporting Documentation", - author, - "manual", - ) -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# latex_use_parts = False - -# If true, show page references after internal links. -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# latex_appendices = [] - -# If false, no module index is generated. -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ( - root_doc, - "google-cloud-error-reporting", - "google-cloud-error-reporting Documentation", - [author], - 1, - ) -] - -# If true, show URL addresses after external links. -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ( - root_doc, - "google-cloud-error-reporting", - "google-cloud-error-reporting Documentation", - author, - "google-cloud-error-reporting", - "google-cloud-error-reporting Library", - "APIs", - ) -] - -# Documents to append as an appendix to all manuals. -# texinfo_appendices = [] - -# If false, no module index is generated. -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# texinfo_no_detailmenu = False - - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = { - "python": ("https://python.readthedocs.org/en/latest/", None), - "google-auth": ("https://googleapis.dev/python/google-auth/latest/", None), - "google.api_core": ( - "https://googleapis.dev/python/google-api-core/latest/", - None, - ), - "grpc": ("https://grpc.github.io/grpc/python/", None), - "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), - "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), -} - - -# Napoleon settings -napoleon_google_docstring = True -napoleon_numpy_docstring = True -napoleon_include_private_with_doc = False -napoleon_include_special_with_doc = True -napoleon_use_admonition_for_examples = False -napoleon_use_admonition_for_notes = False -napoleon_use_admonition_for_references = False -napoleon_use_ivar = False -napoleon_use_param = True -napoleon_use_rtype = True - - -# Setup for sphinx behaviors such as warning filters. -class UnexpectedUnindentFilter(logging.Filter): - """Filter out warnings about unexpected unindentation following bullet lists.""" - - def filter(self, record: logging.LogRecord) -> bool: - """Filter the log record. - - Args: - record (logging.LogRecord): The log record. - - Returns: - bool: False to suppress the warning, True to allow it. - """ - msg = record.getMessage() - if "Bullet list ends without a blank line" in msg: - return False - return True - - -def setup(app: Any) -> None: - """Setup the Sphinx application. - - Args: - app (Any): The Sphinx application. - """ - # Sphinx's logger is hierarchical. Adding a filter to the - # root 'sphinx' logger will catch warnings from all sub-loggers. - logger = logging.getLogger("sphinx") - logger.addFilter(UnexpectedUnindentFilter()) diff --git a/docs/errorreporting_v1beta1/error_group_service.rst b/docs/errorreporting_v1beta1/error_group_service.rst deleted file mode 100644 index dd213525..00000000 --- a/docs/errorreporting_v1beta1/error_group_service.rst +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100644 index b798b28d..00000000 --- a/docs/errorreporting_v1beta1/error_stats_service.rst +++ /dev/null @@ -1,10 +0,0 @@ -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 deleted file mode 100644 index ccddb8b0..00000000 --- a/docs/errorreporting_v1beta1/report_errors_service.rst +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100644 index e888027f..00000000 --- a/docs/errorreporting_v1beta1/services_.rst +++ /dev/null @@ -1,8 +0,0 @@ -Services for Google Cloud Errorreporting v1beta1 API -==================================================== -.. toctree:: - :maxdepth: 2 - - error_group_service - error_stats_service - report_errors_service diff --git a/docs/errorreporting_v1beta1/types_.rst b/docs/errorreporting_v1beta1/types_.rst deleted file mode 100644 index 08851dbe..00000000 --- a/docs/errorreporting_v1beta1/types_.rst +++ /dev/null @@ -1,6 +0,0 @@ -Types for Google Cloud Errorreporting v1beta1 API -================================================= - -.. automodule:: google.cloud.errorreporting_v1beta1.types - :members: - :show-inheritance: diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index a33c831a..00000000 --- a/docs/index.rst +++ /dev/null @@ -1,39 +0,0 @@ -.. include:: README.rst - -.. include:: multiprocessing.rst - -Usage Documentation -------------------- - -.. toctree:: - :maxdepth: 2 - - usage - - -API Reference -------------- -.. toctree:: - :maxdepth: 2 - - - client - util - errorreporting_v1beta1/services_ - errorreporting_v1beta1/types_ - - -Changelog ---------- - -For a list of all ``google-cloud-error-reporting`` releases: - -.. toctree:: - :maxdepth: 2 - - changelog - -.. toctree:: - :hidden: - - summary_overview.md diff --git a/docs/multiprocessing.rst b/docs/multiprocessing.rst deleted file mode 100644 index 536d17b2..00000000 --- a/docs/multiprocessing.rst +++ /dev/null @@ -1,7 +0,0 @@ -.. note:: - - Because this client uses :mod:`grpc` library, it is safe to - share instances across threads. In multiprocessing scenarios, the best - practice is to create client instances *after* the invocation of - :func:`os.fork` by :class:`multiprocessing.pool.Pool` or - :class:`multiprocessing.Process`. diff --git a/docs/summary_overview.md b/docs/summary_overview.md deleted file mode 100644 index dd16632d..00000000 --- a/docs/summary_overview.md +++ /dev/null @@ -1,22 +0,0 @@ -[ -This is a templated file. Adding content to this file may result in it being -reverted. Instead, if you want to place additional content, create an -"overview_content.md" file in `docs/` directory. The Sphinx tool will -pick up on the content and merge the content. -]: # - -# Error Reporting API - -Overview of the APIs available for Error Reporting API. - -## All entries - -Classes, methods and properties & attributes for -Error Reporting API. - -[classes](https://cloud.google.com/python/docs/reference/clouderrorreporting/latest/summary_class.html) - -[methods](https://cloud.google.com/python/docs/reference/clouderrorreporting/latest/summary_method.html) - -[properties and -attributes](https://cloud.google.com/python/docs/reference/clouderrorreporting/latest/summary_property.html) diff --git a/docs/usage.rst b/docs/usage.rst deleted file mode 100644 index 7f1dc4f7..00000000 --- a/docs/usage.rst +++ /dev/null @@ -1,115 +0,0 @@ -Using Error Reporting -================================= - -After configuring your environment, create a -:class:`Client ` - -.. code-block:: python - - from google.cloud import error_reporting - - client = error_reporting.Client() - -or pass in ``credentials`` and ``project`` explicitly - -.. code-block:: python - - from google.cloud import error_reporting - - client = error_reporting.Client(project='my-project', credentials=creds) - -Error Reporting associates errors with a service, which is an identifier for -an executable, App Engine service, or job. The default service is "python", -but a default can be specified for the client on construction time. You can -also optionally specify a version for that service, which defaults to -"default." - -.. code-block:: python - - from google.cloud import error_reporting - - client = error_reporting.Client( - project='my-project', service="login_service", version="0.1.0") - - -Reporting an exception ------------------------ - -Report a stacktrace to Error Reporting after an exception: - -.. code-block:: python - - from google.cloud import error_reporting - - client = error_reporting.Client() - try: - raise NameError - except Exception: - client.report_exception() - - -By default, the client will report the error using the service specified in -the client's constructor, or the default service of "python". - -The user and HTTP context can also be included in the exception. The HTTP -context can be constructed using -:class:`google.cloud.error_reporting.HTTPContext`. This will be used by -Error Reporting to help group exceptions. - -.. code-block:: python - - from google.cloud import error_reporting - - client = error_reporting.Client() - user = 'example@gmail.com' - http_context = error_reporting.HTTPContext( - method='GET', url='/', user_agent='test agent', - referrer='example.com', response_status_code=500, - remote_ip='1.2.3.4') - try: - raise NameError - except Exception: - client.report_exception(http_context=http_context, user=user)) - -An automatic helper to build the HTTP Context from a Flask (Werkzeug) request -object is provided. - -.. code-block:: python - - from google.cloud.error_reporting import build_flask_context - - @app.errorhandler(HTTPException) - def handle_error(exc): - client.report_exception( - http_context=build_flask_context(request)) - # rest of error response code here - - -Reporting an error without an exception ------------------------------------------ - -Errors can also be reported to Error Reporting outside the context -of an exception. The library will include the file path, function name, and -line number of the location where the error was reported. - -.. code-block:: python - - from google.cloud import error_reporting - - client = error_reporting.Client() - client.report("Found an error!") - -As with reporting an exception, the user and HTTP context can be provided: - -.. code-block:: python - - from google.cloud import error_reporting - - client = error_reporting.Client() - user = 'example@gmail.com' - http_context = error_reporting.HTTPContext( - method='GET', url='/', user_agent='test agent', - referrer='example.com', response_status_code=500, - remote_ip='1.2.3.4') - client.report( - "Found an error!", http_context=http_context, user=user)) diff --git a/docs/util.rst b/docs/util.rst deleted file mode 100644 index 9bc8aad5..00000000 --- a/docs/util.rst +++ /dev/null @@ -1,6 +0,0 @@ -Error Reporting Utilities -========================= - -.. automodule:: google.cloud.error_reporting.util - :members: - :show-inheritance: diff --git a/google/cloud/error_reporting/__init__.py b/google/cloud/error_reporting/__init__.py deleted file mode 100644 index 1b729821..00000000 --- a/google/cloud/error_reporting/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2016 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Client library for Error Reporting""" - - -from google.cloud.error_reporting import gapic_version as package_version - -__version__ = package_version.__version__ - -from google.cloud.error_reporting.client import Client -from google.cloud.error_reporting.client import HTTPContext -from google.cloud.error_reporting.util import build_flask_context - -__all__ = ["__version__", "Client", "HTTPContext", "build_flask_context"] diff --git a/google/cloud/error_reporting/_gapic.py b/google/cloud/error_reporting/_gapic.py deleted file mode 100644 index d38adf29..00000000 --- a/google/cloud/error_reporting/_gapic.py +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright 2016 Google LLC All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""GAX wrapper for Error Reporting API requests.""" -import json - -import google.cloud.errorreporting_v1beta1 - - -def make_report_error_api(client): - """Create an instance of the gapic Logging API. - - :type client::class:`google.cloud.error_reporting.Client` - :param client: Error Reporting client. - - :rtype: :class:_ErrorReportingGapicApi - :returns: An Error Reporting API instance. - """ - gapic_api = google.cloud.errorreporting_v1beta1.ReportErrorsServiceClient( - credentials=client._credentials, - client_info=client._client_info, - client_options=client._client_options, - ) - return _ErrorReportingGapicApi(gapic_api, client.project) - - -class _ErrorReportingGapicApi(object): - """Helper mapping Error Reporting-related APIs - - :type gapic: - :class:`google.cloud.errorreporting_v1beta1.ReportErrorsServiceClient` - :param gapic: API object used to make RPCs. - - :type project: str - :param project: Google Cloud Project ID - """ - - def __init__(self, gapic_api, project): - self._gapic_api = gapic_api - self._project = project - - def report_error_event(self, error_report): - """Uses the gapic client to report the error. - - :type error_report: dict - :param error_report: - payload of the error report formatted according to - https://cloud.google.com/error-reporting/docs/formatting-error-messages - This object should be built using - Use - :meth:~`google.cloud.error_reporting.client._build_error_report` - """ - project_name = f"projects/{self._project}" - - # Since error_report uses camel case for key names (like serviceContext), - # but ReportedErrorEvent uses snake case for key names (like service_context), - # we need to route throught json. - error_report_payload = ( - google.cloud.errorreporting_v1beta1.ReportedErrorEvent.from_json( - json.dumps(error_report) - ) - ) - - self._gapic_api.report_error_event( - project_name=project_name, event=error_report_payload - ) diff --git a/google/cloud/error_reporting/_logging.py b/google/cloud/error_reporting/_logging.py deleted file mode 100644 index c7d1d909..00000000 --- a/google/cloud/error_reporting/_logging.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright 2016 Google LLC All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Interact with Error Reporting via Logging API. - -It's possible to report Error Reporting errors by formatting -structured log messages in Cloud Logging in a given format. This -client provides a mechanism to report errors using that technique. -""" - -import google.cloud.logging - - -class _ErrorReportingLoggingAPI(object): - """Report to Error Reporting via Logging API - - :type project: str - :param project: the project which the client acts on behalf of. If not - passed falls back to the default inferred from the - environment. - - :type credentials: :class:`google.auth.credentials.Credentials` or - :class:`NoneType` - :param credentials: The authorization credentials to attach to requests. - These credentials identify this application to the service. - If none are specified, the client will attempt to ascertain - the credentials from the environment. - - :type _http: :class:`~requests.Session` - :param _http: (Optional) HTTP object to make requests. Can be any object - that defines ``request()`` with the same interface as - :meth:`requests.Session.request`. If not passed, an - ``_http`` object is created that is bound to the - ``credentials`` for the current object. - This parameter should be considered private, and could - change in the future. - - :type client_info: - :class:`google.api_core.client_info.ClientInfo` or - :class:`google.api_core.gapic_v1.client_info.ClientInfo` - :param client_info: - 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 library - or partner tool. - - :type client_options: :class:`~google.api_core.client_options.ClientOptions` - or :class:`dict` - :param client_options: (Optional) Client options used to set user options - on the client. API Endpoint should be set through client_options. - """ - - def __init__( - self, - project, - credentials=None, - _http=None, - client_info=None, - client_options=None, - ): - self.logging_client = google.cloud.logging.Client( - project=project, - credentials=credentials, - _http=_http, - client_info=client_info, - client_options=client_options, - ) - - def report_error_event(self, error_report): - """Report error payload. - - :type error_report: dict - :param: error_report: - dict payload of the error report formatted according to - https://cloud.google.com/error-reporting/docs/formatting-error-messages - This object should be built using - :meth:~`google.cloud.error_reporting.client._build_error_report` - """ - logger = self.logging_client.logger("errors") - logger.log_struct(error_report) diff --git a/google/cloud/error_reporting/client.py b/google/cloud/error_reporting/client.py deleted file mode 100644 index 440262da..00000000 --- a/google/cloud/error_reporting/client.py +++ /dev/null @@ -1,387 +0,0 @@ -# Copyright 2016 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Client for interacting with the Error Reporting API""" - -import os -import traceback - -try: - from google.cloud.error_reporting._gapic import make_report_error_api -except ImportError: # pragma: NO COVER - from google.api_core import client_info # noqa - - _HAVE_GRPC = False -else: - from google.api_core.gapic_v1 import client_info - - _HAVE_GRPC = True - -from google.cloud.client import ClientWithProject -from google.cloud.error_reporting import __version__ -from google.cloud.error_reporting._logging import _ErrorReportingLoggingAPI -from google.cloud.environment_vars import DISABLE_GRPC - -_DISABLE_GRPC = os.getenv(DISABLE_GRPC, False) -_USE_GRPC = _HAVE_GRPC and not _DISABLE_GRPC -_CLIENT_INFO = client_info.ClientInfo(client_library_version=__version__) - - -class HTTPContext(object): - """HTTPContext defines an object that captures the parameter for the - httpRequest part of Error Reporting API - - :type method: str - :param method: The type of HTTP request, such as GET, POST, etc. - - :type url: str - :param url: The URL of the request - - :type user_agent: str - :param user_agent: The user agent information that is provided with the - request. - - :type referrer: str - :param referrer: The referrer information that is provided with the - request. - - :type response_status_code: int - :param response_status_code: The HTTP response status code for the request. - - :type remote_ip: str - :param remote_ip: The IP address from which the request originated. This - can be IPv4, IPv6, or a token which is derived from - the IP address, depending on the data that has been - provided in the error report. - """ - - def __init__( - self, - method=None, - url=None, - user_agent=None, - referrer=None, - response_status_code=None, - remote_ip=None, - ): - self.method = method - self.url = url - # intentionally camel case for mapping to JSON API expects - # pylint: disable=invalid-name - self.userAgent = user_agent - self.referrer = referrer - self.responseStatusCode = response_status_code - self.remoteIp = remote_ip - - -class Client(ClientWithProject): - """Error Reporting client. Currently Error Reporting is done by creating - a Logging client. - - :type project: str - :param project: the project which the client acts on behalf of. If not - passed falls back to the default inferred from the - environment. - - :type credentials: :class:`google.auth.credentials.Credentials` or - :class:`NoneType` - :param credentials: The authorization credentials to attach to requests. - These credentials identify this application to the service. - If none are specified, the client will attempt to ascertain - the credentials from the environment. - - :type _http: :class:`~requests.Session` - :param _http: (Optional) HTTP object to make requests. Can be any object - that defines ``request()`` with the same interface as - :meth:`requests.Session.request`. If not passed, an - ``_http`` object is created that is bound to the - ``credentials`` for the current object. - This parameter should be considered private, and could - change in the future. - - :type service: str - :param service: An identifier of the service, such as the name of the - executable, job, or Google App Engine service name. This - field is expected to have a low number of values that are - relatively stable over time, as opposed to version, - which can be changed whenever new code is deployed. - - - :type version: str - :param version: Represents the source code version that the developer - provided, which could represent a version label or a Git - SHA-1 hash, for example. If the developer did not provide - a version, the value is set to default. - - :type _use_grpc: bool - :param _use_grpc: (Optional) Explicitly specifies whether - to use the gRPC transport or HTTP. If unset, - falls back to the ``GOOGLE_CLOUD_DISABLE_GRPC`` - environment variable. - This parameter should be considered private, and could - change in the future. - - :type client_info: - :class:`google.api_core.client_info.ClientInfo` or - :class:`google.api_core.gapic_v1.client_info.ClientInfo` - :param client_info: - 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 library - or partner tool. - - :type client_options: :class:`~google.api_core.client_options.ClientOptions` - or :class:`dict` - :param client_options: (Optional) Client options used to set user options - on the client. API Endpoint should be set through client_options. - - :raises: :class:`ValueError` if the project is neither passed in nor - set in the environment. - """ - - SCOPE = ("https://www.googleapis.com/auth/cloud-platform",) - """The scopes required for authenticating as an API consumer.""" - - def __init__( - self, - project=None, - credentials=None, - _http=None, - service=None, - version=None, - client_info=_CLIENT_INFO, - client_options=None, - _use_grpc=None, - ): - super(Client, self).__init__( - project=project, credentials=credentials, _http=_http - ) - self._report_errors_api = None - - self.service = service if service else self.DEFAULT_SERVICE - self.version = version - self._client_info = client_info - self._client_options = client_options - - if _use_grpc is None: - self._use_grpc = _USE_GRPC - else: - self._use_grpc = _use_grpc - - DEFAULT_SERVICE = "python" - - @property - def report_errors_api(self): - """Helper for logging-related API calls. - - See - https://cloud.google.com/logging/docs/reference/v2/rest/v2/entries - https://cloud.google.com/logging/docs/reference/v2/rest/v2/projects.logs - - :rtype: - :class:`_gapic._ErrorReportingGapicApi` - or - :class:`._logging._ErrorReportingLoggingAPI` - :returns: A class that implements the report errors API. - """ - if self._report_errors_api is None: - if self._use_grpc: - self._report_errors_api = make_report_error_api(self) - else: - self._report_errors_api = _ErrorReportingLoggingAPI( - self.project, - self._credentials, - self._http, - self._client_info, - self._client_options, - ) - return self._report_errors_api - - def _build_error_report( - self, message, report_location=None, http_context=None, user=None - ): - """Builds the Error Reporting object to report. - - This builds the object according to - - https://cloud.google.com/error-reporting/docs/formatting-error-messages - - :type message: str - :param message: The stack trace that was reported or logged by the - service. - - :type report_location: dict - :param report_location: 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 exception this would be the - source line where the exception is logged, usually close to - the place where it was caught. - - This should be a Python dict that contains the keys 'filePath', - 'lineNumber', and 'functionName' - - :type http_context: :class`google.cloud.error_reporting.HTTPContext` - :param http_context: The HTTP request which was processed when the - error was triggered. - - :type user: str - :param user: The user who caused or was affected by the crash. This can - be a user ID, an email address, or an arbitrary token that - uniquely identifies the user. When sending an error - report, leave this field empty if the user was not - logged in. In this case the Error Reporting system will - use other data, such as remote IP address, - to distinguish affected users. - :rtype: dict - :returns: A dict payload ready to be serialized to JSON and sent to - the API. - """ - payload = { - "serviceContext": {"service": self.service}, - "message": "{0}".format(message), - } - - if self.version: - payload["serviceContext"]["version"] = self.version - - if report_location or http_context or user: - payload["context"] = {} - - if report_location: - payload["context"]["reportLocation"] = report_location - - if http_context: - http_context_dict = http_context.__dict__ - # strip out None values - payload["context"]["httpRequest"] = { - key: value - for key, value in http_context_dict.items() - if value is not None - } - if user: - payload["context"]["user"] = user - return payload - - def _send_error_report( - self, message, report_location=None, http_context=None, user=None - ): - """Makes the call to the Error Reporting API. - - This is the lower-level interface to build and send the payload, - generally users will use either report() or report_exception() to - automatically gather the parameters for this method. - - :type message: str - :param message: The stack trace that was reported or logged by the - service. - - :type report_location: dict - :param report_location: 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 exception this would be the - source line where the exception is logged, usually close to - the place where it was caught. - - This should be a Python dict that contains the keys 'filePath', - 'lineNumber', and 'functionName' - - :type http_context: :class`google.cloud.error_reporting.HTTPContext` - :param http_context: The HTTP request which was processed when the - error was triggered. - - :type user: str - :param user: The user who caused or was affected by the crash. This can - be a user ID, an email address, or an arbitrary token that - uniquely identifies the user. When sending an error - report, leave this field empty if the user was not - logged in. In this case the Error Reporting system will - use other data, such as remote IP address, - to distinguish affected users. - """ - error_report = self._build_error_report( - message, report_location, http_context, user - ) - self.report_errors_api.report_error_event(error_report) - - def report(self, message, http_context=None, user=None): - """Reports a message to Error Reporting - - https://cloud.google.com/error-reporting/docs/formatting-error-messages - - :type message: str - :param message: A user-supplied message to report - - :type http_context: :class`google.cloud.error_reporting.HTTPContext` - :param http_context: The HTTP request which was processed when the - error was triggered. - - :type user: str - :param user: The user who caused or was affected by the crash. This - can be a user ID, an email address, or an arbitrary - token that uniquely identifies the user. When sending - an error report, leave this field empty if the user - was not logged in. In this case the Error Reporting - system will use other data, such as remote IP address, - to distinguish affected users. - - Example: - - .. code-block:: python - - >>> client.report("Something went wrong!") - """ - stack = traceback.extract_stack() - last_call = stack[-2] - file_path = last_call[0] - line_number = last_call[1] - function_name = last_call[2] - report_location = { - "filePath": file_path, - "lineNumber": line_number, - "functionName": function_name, - } - - self._send_error_report( - message, - http_context=http_context, - user=user, - report_location=report_location, - ) - - def report_exception(self, http_context=None, user=None): - """Reports the details of the latest exceptions to Error Reporting. - - :type http_context: :class`google.cloud.error_reporting.HTTPContext` - :param http_context: The HTTP request which was processed when the - error was triggered. - - :type user: str - :param user: The user who caused or was affected by the crash. This - can be a user ID, an email address, or an arbitrary - token that uniquely identifies the user. When sending an - error report, leave this field empty if the user was - not logged in. In this case the Error Reporting system - will use other data, such as remote IP address, - to distinguish affected users. - - Example:: - - >>> try: - >>> raise NameError - >>> except Exception: - >>> client.report_exception() - """ - self._send_error_report( - traceback.format_exc(), http_context=http_context, user=user - ) diff --git a/google/cloud/error_reporting/gapic_version.py b/google/cloud/error_reporting/gapic_version.py deleted file mode 100644 index 624a2e53..00000000 --- a/google/cloud/error_reporting/gapic_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -__version__ = "1.14.0" # {x-release-please-version} diff --git a/google/cloud/error_reporting/util.py b/google/cloud/error_reporting/util.py deleted file mode 100644 index 8f8434e9..00000000 --- a/google/cloud/error_reporting/util.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2016 Google LLC All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Utility functions for Error Reporting.""" - -from google.cloud.error_reporting.client import HTTPContext - - -def build_flask_context(request): - """Builds an HTTP context object from a Flask (Werkzeug) request object. - - This helper method extracts the relevant HTTP context from a Flask request - object into an object ready to be sent to Error Reporting. - - .. code-block:: python - - >>> @app.errorhandler(HTTPException) - ... def handle_error(exc): - ... client.report_exception( - ... http_context=build_flask_context(request)) - ... # rest of error response code here - - :type request: :class:`werkzeug.wrappers.request` - :param request: The Flask request object to convert. - - :rtype: :class:`~google.cloud.error_reporting.client.HTTPContext` - :returns: An HTTPContext object ready to be sent to the Error Reporting - API. - """ - return HTTPContext( - url=request.url, - method=request.method, - user_agent=request.user_agent.string, - referrer=request.referrer, - remote_ip=request.remote_addr, - ) diff --git a/google/cloud/errorreporting_v1beta1/__init__.py b/google/cloud/errorreporting_v1beta1/__init__.py deleted file mode 100644 index 82b5b2ee..00000000 --- a/google/cloud/errorreporting_v1beta1/__init__.py +++ /dev/null @@ -1,190 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from google.cloud.errorreporting_v1beta1 import gapic_version as package_version - -import google.api_core as api_core -import sys - -__version__ = package_version.__version__ - -if sys.version_info >= (3, 8): # pragma: NO COVER - from importlib import metadata -else: # pragma: NO COVER - # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove - # this code path once we drop support for Python 3.7 - import importlib_metadata as metadata - - -from .services.error_group_service import ErrorGroupServiceClient -from .services.error_group_service import ErrorGroupServiceAsyncClient -from .services.error_stats_service import ErrorStatsServiceClient -from .services.error_stats_service import ErrorStatsServiceAsyncClient -from .services.report_errors_service import ReportErrorsServiceClient -from .services.report_errors_service import ReportErrorsServiceAsyncClient - -from .types.common import ErrorContext -from .types.common import ErrorEvent -from .types.common import ErrorGroup -from .types.common import HttpRequestContext -from .types.common import ServiceContext -from .types.common import SourceLocation -from .types.common import TrackingIssue -from .types.common import ResolutionStatus -from .types.error_group_service import GetGroupRequest -from .types.error_group_service import UpdateGroupRequest -from .types.error_stats_service import DeleteEventsRequest -from .types.error_stats_service import DeleteEventsResponse -from .types.error_stats_service import ErrorGroupStats -from .types.error_stats_service import ListEventsRequest -from .types.error_stats_service import ListEventsResponse -from .types.error_stats_service import ListGroupStatsRequest -from .types.error_stats_service import ListGroupStatsResponse -from .types.error_stats_service import QueryTimeRange -from .types.error_stats_service import ServiceContextFilter -from .types.error_stats_service import TimedCount -from .types.error_stats_service import ErrorGroupOrder -from .types.error_stats_service import TimedCountAlignment -from .types.report_errors_service import ReportedErrorEvent -from .types.report_errors_service import ReportErrorEventRequest -from .types.report_errors_service import ReportErrorEventResponse - -if hasattr(api_core, "check_python_version") and hasattr( - api_core, "check_dependency_versions" -): # pragma: NO COVER - api_core.check_python_version("google.cloud.errorreporting_v1beta1") # type: ignore - api_core.check_dependency_versions("google.cloud.errorreporting_v1beta1") # type: ignore -else: # pragma: NO COVER - # An older version of api_core is installed which does not define the - # functions above. We do equivalent checks manually. - try: - import warnings - import sys - - _py_version_str = sys.version.split()[0] - _package_label = "google.cloud.errorreporting_v1beta1" - if sys.version_info < (3, 9): - warnings.warn( - "You are using a non-supported Python version " - + f"({_py_version_str}). Google will not post any further " - + f"updates to {_package_label} supporting this Python version. " - + "Please upgrade to the latest Python version, or at " - + f"least to Python 3.9, and then update {_package_label}.", - FutureWarning, - ) - if sys.version_info[:2] == (3, 9): - warnings.warn( - f"You are using a Python version ({_py_version_str}) " - + f"which Google will stop supporting in {_package_label} in " - + "January 2026. Please " - + "upgrade to the latest Python version, or at " - + "least to Python 3.10, before then, and " - + f"then update {_package_label}.", - FutureWarning, - ) - - def parse_version_to_tuple(version_string: str): - """Safely converts a semantic version string to a comparable tuple of integers. - Example: "4.25.8" -> (4, 25, 8) - Ignores non-numeric parts and handles common version formats. - Args: - version_string: Version string in the format "x.y.z" or "x.y.z" - Returns: - Tuple of integers for the parsed version string. - """ - parts = [] - for part in version_string.split("."): - try: - parts.append(int(part)) - except ValueError: - # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. - # This is a simplification compared to 'packaging.parse_version', but sufficient - # for comparing strictly numeric semantic versions. - break - return tuple(parts) - - def _get_version(dependency_name): - try: - version_string: str = metadata.version(dependency_name) - parsed_version = parse_version_to_tuple(version_string) - return (parsed_version, version_string) - except Exception: - # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) - # or errors during parse_version_to_tuple - return (None, "--") - - _dependency_package = "google.protobuf" - _next_supported_version = "4.25.8" - _next_supported_version_tuple = (4, 25, 8) - _recommendation = " (we recommend 6.x)" - (_version_used, _version_used_string) = _get_version(_dependency_package) - if _version_used and _version_used < _next_supported_version_tuple: - warnings.warn( - f"Package {_package_label} depends on " - + f"{_dependency_package}, currently installed at version " - + f"{_version_used_string}. Future updates to " - + f"{_package_label} will require {_dependency_package} at " - + f"version {_next_supported_version} or higher{_recommendation}." - + " Please ensure " - + "that either (a) your Python environment doesn't pin the " - + f"version of {_dependency_package}, so that updates to " - + f"{_package_label} can require the higher version, or " - + "(b) you manually update your Python environment to use at " - + f"least version {_next_supported_version} of " - + f"{_dependency_package}.", - FutureWarning, - ) - except Exception: - warnings.warn( - "Could not determine the version of Python " - + "currently being used. To continue receiving " - + "updates for {_package_label}, ensure you are " - + "using a supported version of Python; see " - + "https://devguide.python.org/versions/" - ) - -__all__ = ( - "ErrorGroupServiceAsyncClient", - "ErrorStatsServiceAsyncClient", - "ReportErrorsServiceAsyncClient", - "DeleteEventsRequest", - "DeleteEventsResponse", - "ErrorContext", - "ErrorEvent", - "ErrorGroup", - "ErrorGroupOrder", - "ErrorGroupServiceClient", - "ErrorGroupStats", - "ErrorStatsServiceClient", - "GetGroupRequest", - "HttpRequestContext", - "ListEventsRequest", - "ListEventsResponse", - "ListGroupStatsRequest", - "ListGroupStatsResponse", - "QueryTimeRange", - "ReportErrorEventRequest", - "ReportErrorEventResponse", - "ReportErrorsServiceClient", - "ReportedErrorEvent", - "ResolutionStatus", - "ServiceContext", - "ServiceContextFilter", - "SourceLocation", - "TimedCount", - "TimedCountAlignment", - "TrackingIssue", - "UpdateGroupRequest", -) diff --git a/google/cloud/errorreporting_v1beta1/gapic_metadata.json b/google/cloud/errorreporting_v1beta1/gapic_metadata.json deleted file mode 100644 index 825275e6..00000000 --- a/google/cloud/errorreporting_v1beta1/gapic_metadata.json +++ /dev/null @@ -1,156 +0,0 @@ - { - "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", - "language": "python", - "libraryPackage": "google.cloud.errorreporting_v1beta1", - "protoPackage": "google.devtools.clouderrorreporting.v1beta1", - "schema": "1.0", - "services": { - "ErrorGroupService": { - "clients": { - "grpc": { - "libraryClient": "ErrorGroupServiceClient", - "rpcs": { - "GetGroup": { - "methods": [ - "get_group" - ] - }, - "UpdateGroup": { - "methods": [ - "update_group" - ] - } - } - }, - "grpc-async": { - "libraryClient": "ErrorGroupServiceAsyncClient", - "rpcs": { - "GetGroup": { - "methods": [ - "get_group" - ] - }, - "UpdateGroup": { - "methods": [ - "update_group" - ] - } - } - }, - "rest": { - "libraryClient": "ErrorGroupServiceClient", - "rpcs": { - "GetGroup": { - "methods": [ - "get_group" - ] - }, - "UpdateGroup": { - "methods": [ - "update_group" - ] - } - } - } - } - }, - "ErrorStatsService": { - "clients": { - "grpc": { - "libraryClient": "ErrorStatsServiceClient", - "rpcs": { - "DeleteEvents": { - "methods": [ - "delete_events" - ] - }, - "ListEvents": { - "methods": [ - "list_events" - ] - }, - "ListGroupStats": { - "methods": [ - "list_group_stats" - ] - } - } - }, - "grpc-async": { - "libraryClient": "ErrorStatsServiceAsyncClient", - "rpcs": { - "DeleteEvents": { - "methods": [ - "delete_events" - ] - }, - "ListEvents": { - "methods": [ - "list_events" - ] - }, - "ListGroupStats": { - "methods": [ - "list_group_stats" - ] - } - } - }, - "rest": { - "libraryClient": "ErrorStatsServiceClient", - "rpcs": { - "DeleteEvents": { - "methods": [ - "delete_events" - ] - }, - "ListEvents": { - "methods": [ - "list_events" - ] - }, - "ListGroupStats": { - "methods": [ - "list_group_stats" - ] - } - } - } - } - }, - "ReportErrorsService": { - "clients": { - "grpc": { - "libraryClient": "ReportErrorsServiceClient", - "rpcs": { - "ReportErrorEvent": { - "methods": [ - "report_error_event" - ] - } - } - }, - "grpc-async": { - "libraryClient": "ReportErrorsServiceAsyncClient", - "rpcs": { - "ReportErrorEvent": { - "methods": [ - "report_error_event" - ] - } - } - }, - "rest": { - "libraryClient": "ReportErrorsServiceClient", - "rpcs": { - "ReportErrorEvent": { - "methods": [ - "report_error_event" - ] - } - } - } - } - } - } -} diff --git a/google/cloud/errorreporting_v1beta1/gapic_version.py b/google/cloud/errorreporting_v1beta1/gapic_version.py deleted file mode 100644 index 750bf9a8..00000000 --- a/google/cloud/errorreporting_v1beta1/gapic_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -__version__ = "1.14.0" # {x-release-please-version} diff --git a/google/cloud/errorreporting_v1beta1/py.typed b/google/cloud/errorreporting_v1beta1/py.typed deleted file mode 100644 index 01870137..00000000 --- a/google/cloud/errorreporting_v1beta1/py.typed +++ /dev/null @@ -1,2 +0,0 @@ -# Marker file for PEP 561. -# The google-cloud-error-reporting package uses inline types. diff --git a/google/cloud/errorreporting_v1beta1/services/__init__.py b/google/cloud/errorreporting_v1beta1/services/__init__.py deleted file mode 100644 index cbf94b28..00000000 --- a/google/cloud/errorreporting_v1beta1/services/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/google/cloud/errorreporting_v1beta1/services/error_group_service/__init__.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/__init__.py deleted file mode 100644 index 1e8d42ee..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_group_service/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .client import ErrorGroupServiceClient -from .async_client import ErrorGroupServiceAsyncClient - -__all__ = ( - "ErrorGroupServiceClient", - "ErrorGroupServiceAsyncClient", -) 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 deleted file mode 100644 index 4074530e..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_group_service/async_client.py +++ /dev/null @@ -1,561 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from collections import OrderedDict -import re -from typing import ( - Dict, - Callable, - Mapping, - MutableMapping, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, -) - -from google.cloud.errorreporting_v1beta1 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.cloud.errorreporting_v1beta1.types import common -from google.cloud.errorreporting_v1beta1.types import error_group_service -from .transports.base import ErrorGroupServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc_asyncio import ErrorGroupServiceGrpcAsyncIOTransport -from .client import ErrorGroupServiceClient - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class ErrorGroupServiceAsyncClient: - """Service for retrieving and updating individual error groups.""" - - _client: ErrorGroupServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ErrorGroupServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ErrorGroupServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ErrorGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE - _DEFAULT_UNIVERSE = ErrorGroupServiceClient._DEFAULT_UNIVERSE - - error_group_path = staticmethod(ErrorGroupServiceClient.error_group_path) - parse_error_group_path = staticmethod( - ErrorGroupServiceClient.parse_error_group_path - ) - common_billing_account_path = staticmethod( - ErrorGroupServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ErrorGroupServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(ErrorGroupServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - ErrorGroupServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ErrorGroupServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ErrorGroupServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod(ErrorGroupServiceClient.common_project_path) - parse_common_project_path = staticmethod( - ErrorGroupServiceClient.parse_common_project_path - ) - common_location_path = staticmethod(ErrorGroupServiceClient.common_location_path) - parse_common_location_path = staticmethod( - ErrorGroupServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ErrorGroupServiceAsyncClient: The constructed client. - """ - sa_info_func = ( - ErrorGroupServiceClient.from_service_account_info.__func__ # type: ignore - ) - return sa_info_func(ErrorGroupServiceAsyncClient, info, *args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ErrorGroupServiceAsyncClient: The constructed client. - """ - sa_file_func = ( - ErrorGroupServiceClient.from_service_account_file.__func__ # type: ignore - ) - return sa_file_func(ErrorGroupServiceAsyncClient, filename, *args, **kwargs) - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ErrorGroupServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ErrorGroupServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ErrorGroupServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ErrorGroupServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ErrorGroupServiceTransport, - Callable[..., ErrorGroupServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the error group service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ErrorGroupServiceTransport,Callable[..., ErrorGroupServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ErrorGroupServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ErrorGroupServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.devtools.clouderrorreporting_v1beta1.ErrorGroupServiceAsyncClient`.", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "universeDomain": getattr( - self._client._transport._credentials, "universe_domain", "" - ), - "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", - "credentialsInfo": getattr( - self.transport._credentials, "get_cred_info", lambda: None - )(), - } - if hasattr(self._client._transport, "_credentials") - else { - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "credentialsType": None, - }, - ) - - async def get_group( - self, - request: Optional[Union[error_group_service.GetGroupRequest, dict]] = None, - *, - group_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> common.ErrorGroup: - r"""Get the specified group. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import errorreporting_v1beta1 - - async def sample_get_group(): - # Create a client - client = errorreporting_v1beta1.ErrorGroupServiceAsyncClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.GetGroupRequest( - group_name="group_name_value", - ) - - # Make the request - response = await client.get_group(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[google.cloud.errorreporting_v1beta1.types.GetGroupRequest, dict]]): - The request object. A request to return an individual - group. - group_name (:class:`str`): - Required. The group resource name. Written as either - ``projects/{projectID}/groups/{group_id}`` or - ``projects/{projectID}/locations/{location}/groups/{group_id}``. - Call [groupStats.list] - [google.devtools.clouderrorreporting.v1beta1.ErrorStatsService.ListGroupStats] - to return a list of groups belonging to this project. - - Examples: ``projects/my-project-123/groups/my-group``, - ``projects/my-project-123/locations/global/groups/my-group`` - - In the group resource name, the ``group_id`` is a unique - identifier for a particular error group. The identifier - is derived from key parts of the error-log content and - is treated as Service Data. For information about how - Service Data is handled, see `Google Cloud Privacy - Notice `__. - - For a list of supported locations, see `Supported - Regions `__. - ``global`` is the default when unspecified. - - This corresponds to the ``group_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud.errorreporting_v1beta1.types.ErrorGroup: - Description of a group of similar - error events. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [group_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, error_group_service.GetGroupRequest): - request = error_group_service.GetGroupRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if group_name is not None: - request.group_name = group_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.get_group - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("group_name", request.group_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def update_group( - self, - request: Optional[Union[error_group_service.UpdateGroupRequest, dict]] = None, - *, - group: Optional[common.ErrorGroup] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> common.ErrorGroup: - r"""Replace the data for the specified group. - Fails if the group does not exist. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import errorreporting_v1beta1 - - async def sample_update_group(): - # Create a client - client = errorreporting_v1beta1.ErrorGroupServiceAsyncClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.UpdateGroupRequest( - ) - - # Make the request - response = await client.update_group(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[google.cloud.errorreporting_v1beta1.types.UpdateGroupRequest, dict]]): - The request object. A request to replace the existing - data for the given group. - 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. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud.errorreporting_v1beta1.types.ErrorGroup: - Description of a group of similar - error events. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [group] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, error_group_service.UpdateGroupRequest): - request = error_group_service.UpdateGroupRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if group is not None: - request.group = group - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.update_group - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("group.name", request.group.name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ErrorGroupServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ErrorGroupServiceAsyncClient",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/client.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/client.py deleted file mode 100644 index 6102fcda..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_group_service/client.py +++ /dev/null @@ -1,989 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - Mapping, - MutableMapping, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.cloud.errorreporting_v1beta1 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - -from google.cloud.errorreporting_v1beta1.types import common -from google.cloud.errorreporting_v1beta1.types import error_group_service -from .transports.base import ErrorGroupServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import ErrorGroupServiceGrpcTransport -from .transports.grpc_asyncio import ErrorGroupServiceGrpcAsyncIOTransport -from .transports.rest import ErrorGroupServiceRestTransport - - -class ErrorGroupServiceClientMeta(type): - """Metaclass for the ErrorGroupService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ErrorGroupServiceTransport]] - _transport_registry["grpc"] = ErrorGroupServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ErrorGroupServiceGrpcAsyncIOTransport - _transport_registry["rest"] = ErrorGroupServiceRestTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ErrorGroupServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ErrorGroupServiceClient(metaclass=ErrorGroupServiceClientMeta): - """Service for retrieving and updating individual error groups.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "clouderrorreporting.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "clouderrorreporting.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @staticmethod - def _use_client_cert_effective(): - """Returns whether client certificate should be used for mTLS if the - google-auth version supports should_use_client_cert automatic mTLS enablement. - - Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. - - Returns: - bool: whether client certificate should be used for mTLS - Raises: - ValueError: (If using a version of google-auth without should_use_client_cert and - GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) - """ - # check if google-auth version supports should_use_client_cert for automatic mTLS enablement - if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER - return mtls.should_use_client_cert() - else: # pragma: NO COVER - # if unsupported, fallback to reading from env var - use_client_cert_str = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - if use_client_cert_str not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" - " either `true` or `false`" - ) - return use_client_cert_str == "true" - - @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 - 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: - ErrorGroupServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file(filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ErrorGroupServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ErrorGroupServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def error_group_path( - project: str, - group: str, - ) -> str: - """Returns a fully-qualified error_group string.""" - return "projects/{project}/groups/{group}".format( - project=project, - group=group, - ) - - @staticmethod - def parse_error_group_path(path: str) -> Dict[str, str]: - """Parses a error_group path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/groups/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = ErrorGroupServiceClient._use_client_cert_effective() - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert: - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = ErrorGroupServiceClient._use_client_cert_effective() - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert, use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ErrorGroupServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ErrorGroupServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ErrorGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], universe_domain_env: Optional[str] - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ErrorGroupServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ErrorGroupServiceTransport, - Callable[..., ErrorGroupServiceTransport], - ] - ] = None, - client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the error group service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ErrorGroupServiceTransport,Callable[..., ErrorGroupServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ErrorGroupServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict(self._client_options) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr(self._client_options, "universe_domain", None) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ErrorGroupServiceClient._read_environment_variables() - self._client_cert_source = ErrorGroupServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - self._universe_domain = ErrorGroupServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # Initialize the universe domain validation. - self._is_universe_domain_valid = False - - if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER - # Setup logging. - client_logging.initialize_logging() - - api_key_value = getattr(self._client_options, "api_key", None) - if api_key_value and credentials: - raise ValueError( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, ErrorGroupServiceTransport) - if transport_provided: - # transport is a ErrorGroupServiceTransport instance. - if credentials or self._client_options.credentials_file or api_key_value: - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(ErrorGroupServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ErrorGroupServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ErrorGroupServiceTransport], - Callable[..., ErrorGroupServiceTransport], - ] = ( - ErrorGroupServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., ErrorGroupServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - api_audience=self._client_options.api_audience, - ) - - if "async" not in str(self._transport): - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.devtools.clouderrorreporting_v1beta1.ErrorGroupServiceClient`.", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "universeDomain": getattr( - self._transport._credentials, "universe_domain", "" - ), - "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", - "credentialsInfo": getattr( - self.transport._credentials, "get_cred_info", lambda: None - )(), - } - if hasattr(self._transport, "_credentials") - else { - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "credentialsType": None, - }, - ) - - def get_group( - self, - request: Optional[Union[error_group_service.GetGroupRequest, dict]] = None, - *, - group_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> common.ErrorGroup: - r"""Get the specified group. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import errorreporting_v1beta1 - - def sample_get_group(): - # Create a client - client = errorreporting_v1beta1.ErrorGroupServiceClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.GetGroupRequest( - group_name="group_name_value", - ) - - # Make the request - response = client.get_group(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud.errorreporting_v1beta1.types.GetGroupRequest, dict]): - The request object. A request to return an individual - group. - group_name (str): - Required. The group resource name. Written as either - ``projects/{projectID}/groups/{group_id}`` or - ``projects/{projectID}/locations/{location}/groups/{group_id}``. - Call [groupStats.list] - [google.devtools.clouderrorreporting.v1beta1.ErrorStatsService.ListGroupStats] - to return a list of groups belonging to this project. - - Examples: ``projects/my-project-123/groups/my-group``, - ``projects/my-project-123/locations/global/groups/my-group`` - - In the group resource name, the ``group_id`` is a unique - identifier for a particular error group. The identifier - is derived from key parts of the error-log content and - is treated as Service Data. For information about how - Service Data is handled, see `Google Cloud Privacy - Notice `__. - - For a list of supported locations, see `Supported - Regions `__. - ``global`` is the default when unspecified. - - This corresponds to the ``group_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud.errorreporting_v1beta1.types.ErrorGroup: - Description of a group of similar - error events. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [group_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, error_group_service.GetGroupRequest): - request = error_group_service.GetGroupRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if group_name is not None: - request.group_name = group_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.get_group] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("group_name", request.group_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def update_group( - self, - request: Optional[Union[error_group_service.UpdateGroupRequest, dict]] = None, - *, - group: Optional[common.ErrorGroup] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> common.ErrorGroup: - r"""Replace the data for the specified group. - Fails if the group does not exist. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import errorreporting_v1beta1 - - def sample_update_group(): - # Create a client - client = errorreporting_v1beta1.ErrorGroupServiceClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.UpdateGroupRequest( - ) - - # Make the request - response = client.update_group(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud.errorreporting_v1beta1.types.UpdateGroupRequest, dict]): - The request object. A request to replace the existing - data for the given group. - 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. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud.errorreporting_v1beta1.types.ErrorGroup: - Description of a group of similar - error events. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [group] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, error_group_service.UpdateGroupRequest): - request = error_group_service.UpdateGroupRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if group is not None: - request.group = group - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.update_group] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("group.name", request.group.name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ErrorGroupServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ErrorGroupServiceClient",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/README.rst b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/README.rst deleted file mode 100644 index a0b01808..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/README.rst +++ /dev/null @@ -1,9 +0,0 @@ - -transport inheritance structure -_______________________________ - -`ErrorGroupServiceTransport` is the ABC for all transports. -- public child `ErrorGroupServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). -- public child `ErrorGroupServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). -- private child `_BaseErrorGroupServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). -- public child `ErrorGroupServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/__init__.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/__init__.py deleted file mode 100644 index f02ba22b..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/__init__.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from typing import Dict, Type - -from .base import ErrorGroupServiceTransport -from .grpc import ErrorGroupServiceGrpcTransport -from .grpc_asyncio import ErrorGroupServiceGrpcAsyncIOTransport -from .rest import ErrorGroupServiceRestTransport -from .rest import ErrorGroupServiceRestInterceptor - - -# Compile a registry of transports. -_transport_registry = OrderedDict() # type: Dict[str, Type[ErrorGroupServiceTransport]] -_transport_registry["grpc"] = ErrorGroupServiceGrpcTransport -_transport_registry["grpc_asyncio"] = ErrorGroupServiceGrpcAsyncIOTransport -_transport_registry["rest"] = ErrorGroupServiceRestTransport - -__all__ = ( - "ErrorGroupServiceTransport", - "ErrorGroupServiceGrpcTransport", - "ErrorGroupServiceGrpcAsyncIOTransport", - "ErrorGroupServiceRestTransport", - "ErrorGroupServiceRestInterceptor", -) 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 deleted file mode 100644 index 4ba98770..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/base.py +++ /dev/null @@ -1,185 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Dict, Optional, Sequence, Union - -from google.cloud.errorreporting_v1beta1 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.cloud.errorreporting_v1beta1.types import common -from google.cloud.errorreporting_v1beta1.types import error_group_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ErrorGroupServiceTransport(abc.ABC): - """Abstract transport class for ErrorGroupService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) - - DEFAULT_HOST: str = "clouderrorreporting.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. This argument will be - removed in the next major version of this library. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - default_scopes=self.AUTH_SCOPES, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - scopes=scopes, - quota_project_id=quota_project_id, - default_scopes=self.AUTH_SCOPES, - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr(service_account.Credentials, "with_always_use_jwt_access") - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.get_group: gapic_v1.method.wrap_method( - self.get_group, - default_timeout=None, - client_info=client_info, - ), - self.update_group: gapic_v1.method.wrap_method( - self.update_group, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def get_group( - self, - ) -> Callable[ - [error_group_service.GetGroupRequest], - Union[common.ErrorGroup, Awaitable[common.ErrorGroup]], - ]: - raise NotImplementedError() - - @property - def update_group( - self, - ) -> Callable[ - [error_group_service.UpdateGroupRequest], - Union[common.ErrorGroup, Awaitable[common.ErrorGroup]], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ErrorGroupServiceTransport",) 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 deleted file mode 100644 index c208fdef..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc.py +++ /dev/null @@ -1,387 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import json -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -import google.auth # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore - -from google.cloud.errorreporting_v1beta1.types import common -from google.cloud.errorreporting_v1beta1.types import error_group_service -from .base import ErrorGroupServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" - - request_metadata = { - key: value.decode("utf-8") if isinstance(value, bytes) else value - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "rpcName": str(client_call_details.method), - "request": grpc_request, - "metadata": grpc_request["metadata"], - }, - ) - response = continuation(client_call_details, request) - if logging_enabled: # pragma: NO COVER - response_metadata = response.trailing_metadata() - # Convert gRPC metadata `` to list of tuples - metadata = ( - dict([(k, str(v)) for k, v in response_metadata]) - if response_metadata - else None - ) - result = response.result() - if isinstance(result, proto.Message): - response_payload = type(result).to_json(result) - elif isinstance(result, google.protobuf.message.Message): - response_payload = MessageToJson(result) - else: - response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" - grpc_response = { - "payload": response_payload, - "metadata": metadata, - "status": "OK", - } - _LOGGER.debug( - f"Received response for {client_call_details.method}.", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ErrorGroupServiceGrpcTransport(ErrorGroupServiceTransport): - """gRPC backend transport for ErrorGroupService. - - Service for retrieving and updating individual error groups. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - This argument will be removed in the next major version of this library. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - self._interceptor = _LoggingClientInterceptor() - self._logged_channel = grpc.intercept_channel( - self._grpc_channel, self._interceptor - ) - - # Wrap messages. This must be done after self._logged_channel exists - self._prep_wrapped_messages(client_info) - - @classmethod - def create_channel( - cls, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. This argument will be - removed in the next major version of this library. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def get_group( - self, - ) -> Callable[[error_group_service.GetGroupRequest], common.ErrorGroup]: - r"""Return a callable for the get group method over gRPC. - - Get the specified group. - - Returns: - Callable[[~.GetGroupRequest], - ~.ErrorGroup]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "get_group" not in self._stubs: - self._stubs["get_group"] = self._logged_channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorGroupService/GetGroup", - request_serializer=error_group_service.GetGroupRequest.serialize, - response_deserializer=common.ErrorGroup.deserialize, - ) - return self._stubs["get_group"] - - @property - def update_group( - self, - ) -> Callable[[error_group_service.UpdateGroupRequest], common.ErrorGroup]: - r"""Return a callable for the update group method over gRPC. - - Replace the data for the specified group. - Fails if the group does not exist. - - Returns: - Callable[[~.UpdateGroupRequest], - ~.ErrorGroup]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "update_group" not in self._stubs: - self._stubs["update_group"] = self._logged_channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorGroupService/UpdateGroup", - request_serializer=error_group_service.UpdateGroupRequest.serialize, - response_deserializer=common.ErrorGroup.deserialize, - ) - return self._stubs["update_group"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ErrorGroupServiceGrpcTransport",) 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 deleted file mode 100644 index bc8d9be0..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,417 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import json -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.api_core import exceptions as core_exceptions -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.cloud.errorreporting_v1beta1.types import common -from google.cloud.errorreporting_v1beta1.types import error_group_service -from .base import ErrorGroupServiceTransport, DEFAULT_CLIENT_INFO -from .grpc import ErrorGroupServiceGrpcTransport - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientAIOInterceptor( - grpc.aio.UnaryUnaryClientInterceptor -): # pragma: NO COVER - async def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" - - request_metadata = { - key: value.decode("utf-8") if isinstance(value, bytes) else value - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "rpcName": str(client_call_details.method), - "request": grpc_request, - "metadata": grpc_request["metadata"], - }, - ) - response = await continuation(client_call_details, request) - if logging_enabled: # pragma: NO COVER - response_metadata = await response.trailing_metadata() - # Convert gRPC metadata `` to list of tuples - metadata = ( - dict([(k, str(v)) for k, v in response_metadata]) - if response_metadata - else None - ) - result = await response - if isinstance(result, proto.Message): - response_payload = type(result).to_json(result) - elif isinstance(result, google.protobuf.message.Message): - response_payload = MessageToJson(result) - else: - response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" - grpc_response = { - "payload": response_payload, - "metadata": metadata, - "status": "OK", - } - _LOGGER.debug( - f"Received response to rpc {client_call_details.method}.", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ErrorGroupServiceGrpcAsyncIOTransport(ErrorGroupServiceTransport): - """gRPC AsyncIO backend transport for ErrorGroupService. - - Service for retrieving and updating individual error groups. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be - removed in the next major version of this library. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - This argument will be removed in the next major version of this library. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - self._interceptor = _LoggingClientAIOInterceptor() - self._grpc_channel._unary_unary_interceptors.append(self._interceptor) - self._logged_channel = self._grpc_channel - self._wrap_with_kind = ( - "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters - ) - # Wrap messages. This must be done after self._logged_channel exists - self._prep_wrapped_messages(client_info) - - @property - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def get_group( - self, - ) -> Callable[[error_group_service.GetGroupRequest], Awaitable[common.ErrorGroup]]: - r"""Return a callable for the get group method over gRPC. - - Get the specified group. - - Returns: - Callable[[~.GetGroupRequest], - Awaitable[~.ErrorGroup]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "get_group" not in self._stubs: - self._stubs["get_group"] = self._logged_channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorGroupService/GetGroup", - request_serializer=error_group_service.GetGroupRequest.serialize, - response_deserializer=common.ErrorGroup.deserialize, - ) - return self._stubs["get_group"] - - @property - def update_group( - self, - ) -> Callable[ - [error_group_service.UpdateGroupRequest], Awaitable[common.ErrorGroup] - ]: - r"""Return a callable for the update group method over gRPC. - - Replace the data for the specified group. - Fails if the group does not exist. - - Returns: - Callable[[~.UpdateGroupRequest], - Awaitable[~.ErrorGroup]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "update_group" not in self._stubs: - self._stubs["update_group"] = self._logged_channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorGroupService/UpdateGroup", - request_serializer=error_group_service.UpdateGroupRequest.serialize, - response_deserializer=common.ErrorGroup.deserialize, - ) - return self._stubs["update_group"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.get_group: self._wrap_method( - self.get_group, - default_timeout=None, - client_info=client_info, - ), - self.update_group: self._wrap_method( - self.update_group, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ErrorGroupServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/rest.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/rest.py deleted file mode 100644 index ecbebae3..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/rest.py +++ /dev/null @@ -1,608 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -import json # type: ignore - -from google.auth.transport.requests import AuthorizedSession # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -from google.api_core import rest_helpers -from google.api_core import rest_streaming -from google.api_core import gapic_v1 -import google.protobuf - -from google.protobuf import json_format - -from requests import __version__ as requests_version -import dataclasses -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union -import warnings - - -from google.cloud.errorreporting_v1beta1.types import common -from google.cloud.errorreporting_v1beta1.types import error_group_service - - -from .rest_base import _BaseErrorGroupServiceRestTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = logging.getLogger(__name__) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, - grpc_version=None, - rest_version=f"requests@{requests_version}", -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ErrorGroupServiceRestInterceptor: - """Interceptor for ErrorGroupService. - - Interceptors are used to manipulate requests, request metadata, and responses - in arbitrary ways. - Example use cases include: - * Logging - * Verifying requests according to service or custom semantics - * Stripping extraneous information from responses - - These use cases and more can be enabled by injecting an - instance of a custom subclass when constructing the ErrorGroupServiceRestTransport. - - .. code-block:: python - class MyCustomErrorGroupServiceInterceptor(ErrorGroupServiceRestInterceptor): - def pre_get_group(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_get_group(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_update_group(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_update_group(self, response): - logging.log(f"Received response: {response}") - return response - - transport = ErrorGroupServiceRestTransport(interceptor=MyCustomErrorGroupServiceInterceptor()) - client = ErrorGroupServiceClient(transport=transport) - - - """ - - def pre_get_group( - self, - request: error_group_service.GetGroupRequest, - metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - error_group_service.GetGroupRequest, Sequence[Tuple[str, Union[str, bytes]]] - ]: - """Pre-rpc interceptor for get_group - - Override in a subclass to manipulate the request or metadata - before they are sent to the ErrorGroupService server. - """ - return request, metadata - - def post_get_group(self, response: common.ErrorGroup) -> common.ErrorGroup: - """Post-rpc interceptor for get_group - - DEPRECATED. Please use the `post_get_group_with_metadata` - interceptor instead. - - Override in a subclass to read or manipulate the response - after it is returned by the ErrorGroupService server but before - it is returned to user code. This `post_get_group` interceptor runs - before the `post_get_group_with_metadata` interceptor. - """ - return response - - def post_get_group_with_metadata( - self, - response: common.ErrorGroup, - metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[common.ErrorGroup, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for get_group - - Override in a subclass to read or manipulate the response or metadata after it - is returned by the ErrorGroupService server but before it is returned to user code. - - We recommend only using this `post_get_group_with_metadata` - interceptor in new development instead of the `post_get_group` interceptor. - When both interceptors are used, this `post_get_group_with_metadata` interceptor runs after the - `post_get_group` interceptor. The (possibly modified) response returned by - `post_get_group` will be passed to - `post_get_group_with_metadata`. - """ - return response, metadata - - def pre_update_group( - self, - request: error_group_service.UpdateGroupRequest, - metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - error_group_service.UpdateGroupRequest, Sequence[Tuple[str, Union[str, bytes]]] - ]: - """Pre-rpc interceptor for update_group - - Override in a subclass to manipulate the request or metadata - before they are sent to the ErrorGroupService server. - """ - return request, metadata - - def post_update_group(self, response: common.ErrorGroup) -> common.ErrorGroup: - """Post-rpc interceptor for update_group - - DEPRECATED. Please use the `post_update_group_with_metadata` - interceptor instead. - - Override in a subclass to read or manipulate the response - after it is returned by the ErrorGroupService server but before - it is returned to user code. This `post_update_group` interceptor runs - before the `post_update_group_with_metadata` interceptor. - """ - return response - - def post_update_group_with_metadata( - self, - response: common.ErrorGroup, - metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[common.ErrorGroup, Sequence[Tuple[str, Union[str, bytes]]]]: - """Post-rpc interceptor for update_group - - Override in a subclass to read or manipulate the response or metadata after it - is returned by the ErrorGroupService server but before it is returned to user code. - - We recommend only using this `post_update_group_with_metadata` - interceptor in new development instead of the `post_update_group` interceptor. - When both interceptors are used, this `post_update_group_with_metadata` interceptor runs after the - `post_update_group` interceptor. The (possibly modified) response returned by - `post_update_group` will be passed to - `post_update_group_with_metadata`. - """ - return response, metadata - - -@dataclasses.dataclass -class ErrorGroupServiceRestStub: - _session: AuthorizedSession - _host: str - _interceptor: ErrorGroupServiceRestInterceptor - - -class ErrorGroupServiceRestTransport(_BaseErrorGroupServiceRestTransport): - """REST backend synchronous transport for ErrorGroupService. - - Service for retrieving and updating individual error groups. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends JSON representations of protocol buffers over HTTP/1.1 - """ - - def __init__( - self, - *, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - url_scheme: str = "https", - interceptor: Optional[ErrorGroupServiceRestInterceptor] = None, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. This argument will be - removed in the next major version of this library. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if ``channel`` is provided. - client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client - certificate to configure mutual TLS HTTP channel. It is ignored - if ``channel`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you are developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - url_scheme: the protocol scheme for the API endpoint. Normally - "https", but for testing or local servers, - "http" can be specified. - """ - # Run the base constructor - # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. - # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the - # credentials object - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - url_scheme=url_scheme, - api_audience=api_audience, - ) - self._session = AuthorizedSession( - self._credentials, default_host=self.DEFAULT_HOST - ) - if client_cert_source_for_mtls: - self._session.configure_mtls_channel(client_cert_source_for_mtls) - self._interceptor = interceptor or ErrorGroupServiceRestInterceptor() - self._prep_wrapped_messages(client_info) - - class _GetGroup( - _BaseErrorGroupServiceRestTransport._BaseGetGroup, ErrorGroupServiceRestStub - ): - def __hash__(self): - return hash("ErrorGroupServiceRestTransport.GetGroup") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None, - ): - uri = transcoded_request["uri"] - method = transcoded_request["method"] - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__( - self, - request: error_group_service.GetGroupRequest, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> common.ErrorGroup: - r"""Call the get group method over HTTP. - - Args: - request (~.error_group_service.GetGroupRequest): - The request object. A request to return an individual - group. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - ~.common.ErrorGroup: - Description of a group of similar - error events. - - """ - - http_options = ( - _BaseErrorGroupServiceRestTransport._BaseGetGroup._get_http_options() - ) - - request, metadata = self._interceptor.pre_get_group(request, metadata) - transcoded_request = _BaseErrorGroupServiceRestTransport._BaseGetGroup._get_transcoded_request( - http_options, request - ) - - # Jsonify the query params - query_params = _BaseErrorGroupServiceRestTransport._BaseGetGroup._get_query_params_json( - transcoded_request - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - logging.DEBUG - ): # pragma: NO COVER - request_url = "{host}{uri}".format( - host=self._host, uri=transcoded_request["uri"] - ) - method = transcoded_request["method"] - try: - request_payload = type(request).to_json(request) - except: - request_payload = None - http_request = { - "payload": request_payload, - "requestMethod": method, - "requestUrl": request_url, - "headers": dict(metadata), - } - _LOGGER.debug( - f"Sending request for google.devtools.clouderrorreporting_v1beta1.ErrorGroupServiceClient.GetGroup", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "rpcName": "GetGroup", - "httpRequest": http_request, - "metadata": http_request["headers"], - }, - ) - - # Send the request - response = ErrorGroupServiceRestTransport._GetGroup._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - ) - - # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception - # subclass. - if response.status_code >= 400: - raise core_exceptions.from_http_response(response) - - # Return the response - resp = common.ErrorGroup() - pb_resp = common.ErrorGroup.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - - resp = self._interceptor.post_get_group(resp) - response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_get_group_with_metadata( - resp, response_metadata - ) - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - logging.DEBUG - ): # pragma: NO COVER - try: - response_payload = common.ErrorGroup.to_json(response) - except: - response_payload = None - http_response = { - "payload": response_payload, - "headers": dict(response.headers), - "status": response.status_code, - } - _LOGGER.debug( - "Received response for google.devtools.clouderrorreporting_v1beta1.ErrorGroupServiceClient.get_group", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "rpcName": "GetGroup", - "metadata": http_response["headers"], - "httpResponse": http_response, - }, - ) - return resp - - class _UpdateGroup( - _BaseErrorGroupServiceRestTransport._BaseUpdateGroup, ErrorGroupServiceRestStub - ): - def __hash__(self): - return hash("ErrorGroupServiceRestTransport.UpdateGroup") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None, - ): - uri = transcoded_request["uri"] - method = transcoded_request["method"] - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, - ) - return response - - def __call__( - self, - request: error_group_service.UpdateGroupRequest, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> common.ErrorGroup: - r"""Call the update group method over HTTP. - - Args: - request (~.error_group_service.UpdateGroupRequest): - The request object. A request to replace the existing - data for the given group. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - ~.common.ErrorGroup: - Description of a group of similar - error events. - - """ - - http_options = ( - _BaseErrorGroupServiceRestTransport._BaseUpdateGroup._get_http_options() - ) - - request, metadata = self._interceptor.pre_update_group(request, metadata) - transcoded_request = _BaseErrorGroupServiceRestTransport._BaseUpdateGroup._get_transcoded_request( - http_options, request - ) - - body = _BaseErrorGroupServiceRestTransport._BaseUpdateGroup._get_request_body_json( - transcoded_request - ) - - # Jsonify the query params - query_params = _BaseErrorGroupServiceRestTransport._BaseUpdateGroup._get_query_params_json( - transcoded_request - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - logging.DEBUG - ): # pragma: NO COVER - request_url = "{host}{uri}".format( - host=self._host, uri=transcoded_request["uri"] - ) - method = transcoded_request["method"] - try: - request_payload = type(request).to_json(request) - except: - request_payload = None - http_request = { - "payload": request_payload, - "requestMethod": method, - "requestUrl": request_url, - "headers": dict(metadata), - } - _LOGGER.debug( - f"Sending request for google.devtools.clouderrorreporting_v1beta1.ErrorGroupServiceClient.UpdateGroup", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "rpcName": "UpdateGroup", - "httpRequest": http_request, - "metadata": http_request["headers"], - }, - ) - - # Send the request - response = ErrorGroupServiceRestTransport._UpdateGroup._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - body, - ) - - # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception - # subclass. - if response.status_code >= 400: - raise core_exceptions.from_http_response(response) - - # Return the response - resp = common.ErrorGroup() - pb_resp = common.ErrorGroup.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - - resp = self._interceptor.post_update_group(resp) - response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_update_group_with_metadata( - resp, response_metadata - ) - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - logging.DEBUG - ): # pragma: NO COVER - try: - response_payload = common.ErrorGroup.to_json(response) - except: - response_payload = None - http_response = { - "payload": response_payload, - "headers": dict(response.headers), - "status": response.status_code, - } - _LOGGER.debug( - "Received response for google.devtools.clouderrorreporting_v1beta1.ErrorGroupServiceClient.update_group", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "rpcName": "UpdateGroup", - "metadata": http_response["headers"], - "httpResponse": http_response, - }, - ) - return resp - - @property - def get_group( - self, - ) -> Callable[[error_group_service.GetGroupRequest], common.ErrorGroup]: - # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. - # In C++ this would require a dynamic_cast - return self._GetGroup(self._session, self._host, self._interceptor) # type: ignore - - @property - def update_group( - self, - ) -> Callable[[error_group_service.UpdateGroupRequest], common.ErrorGroup]: - # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. - # In C++ this would require a dynamic_cast - return self._UpdateGroup(self._session, self._host, self._interceptor) # type: ignore - - @property - def kind(self) -> str: - return "rest" - - def close(self): - self._session.close() - - -__all__ = ("ErrorGroupServiceRestTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/rest_base.py b/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/rest_base.py deleted file mode 100644 index f4330f97..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_group_service/transports/rest_base.py +++ /dev/null @@ -1,207 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import json # type: ignore -from google.api_core import path_template -from google.api_core import gapic_v1 - -from google.protobuf import json_format -from .base import ErrorGroupServiceTransport, DEFAULT_CLIENT_INFO - -import re -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union - - -from google.cloud.errorreporting_v1beta1.types import common -from google.cloud.errorreporting_v1beta1.types import error_group_service - - -class _BaseErrorGroupServiceRestTransport(ErrorGroupServiceTransport): - """Base REST backend transport for ErrorGroupService. - - Note: This class is not meant to be used directly. Use its sync and - async sub-classes instead. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends JSON representations of protocol buffers over HTTP/1.1 - """ - - def __init__( - self, - *, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[Any] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - url_scheme: str = "https", - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[Any]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you are developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - url_scheme: the protocol scheme for the API endpoint. Normally - "https", but for testing or local servers, - "http" can be specified. - """ - # Run the base constructor - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - class _BaseGetGroup: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1beta1/{group_name=projects/*/groups/*}", - }, - { - "method": "get", - "uri": "/v1beta1/{group_name=projects/*/locations/*/groups/*}", - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = error_group_service.GetGroupRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) - ) - query_params.update( - _BaseErrorGroupServiceRestTransport._BaseGetGroup._get_unset_required_fields( - query_params - ) - ) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseUpdateGroup: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [ - { - "method": "put", - "uri": "/v1beta1/{group.name=projects/*/groups/*}", - "body": "group", - }, - { - "method": "put", - "uri": "/v1beta1/{group.name=projects/*/locations/*/groups/*}", - "body": "group", - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = error_group_service.UpdateGroupRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_request_body_json(transcoded_request): - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True - ) - return body - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) - ) - query_params.update( - _BaseErrorGroupServiceRestTransport._BaseUpdateGroup._get_unset_required_fields( - query_params - ) - ) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - -__all__ = ("_BaseErrorGroupServiceRestTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/__init__.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/__init__.py deleted file mode 100644 index e04db91b..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .client import ErrorStatsServiceClient -from .async_client import ErrorStatsServiceAsyncClient - -__all__ = ( - "ErrorStatsServiceClient", - "ErrorStatsServiceAsyncClient", -) 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 deleted file mode 100644 index b0b9b735..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/async_client.py +++ /dev/null @@ -1,767 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from collections import OrderedDict -import re -from typing import ( - Dict, - Callable, - Mapping, - MutableMapping, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, -) - -from google.cloud.errorreporting_v1beta1 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.cloud.errorreporting_v1beta1.services.error_stats_service import pagers -from google.cloud.errorreporting_v1beta1.types import common -from google.cloud.errorreporting_v1beta1.types import error_stats_service -from .transports.base import ErrorStatsServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc_asyncio import ErrorStatsServiceGrpcAsyncIOTransport -from .client import ErrorStatsServiceClient - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class ErrorStatsServiceAsyncClient: - """An API for retrieving and managing error statistics as well - as data for individual events. - """ - - _client: ErrorStatsServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ErrorStatsServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ErrorStatsServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ErrorStatsServiceClient._DEFAULT_ENDPOINT_TEMPLATE - _DEFAULT_UNIVERSE = ErrorStatsServiceClient._DEFAULT_UNIVERSE - - error_group_path = staticmethod(ErrorStatsServiceClient.error_group_path) - parse_error_group_path = staticmethod( - ErrorStatsServiceClient.parse_error_group_path - ) - common_billing_account_path = staticmethod( - ErrorStatsServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ErrorStatsServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(ErrorStatsServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - ErrorStatsServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ErrorStatsServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ErrorStatsServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod(ErrorStatsServiceClient.common_project_path) - parse_common_project_path = staticmethod( - ErrorStatsServiceClient.parse_common_project_path - ) - common_location_path = staticmethod(ErrorStatsServiceClient.common_location_path) - parse_common_location_path = staticmethod( - ErrorStatsServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ErrorStatsServiceAsyncClient: The constructed client. - """ - sa_info_func = ( - ErrorStatsServiceClient.from_service_account_info.__func__ # type: ignore - ) - return sa_info_func(ErrorStatsServiceAsyncClient, info, *args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ErrorStatsServiceAsyncClient: The constructed client. - """ - sa_file_func = ( - ErrorStatsServiceClient.from_service_account_file.__func__ # type: ignore - ) - return sa_file_func(ErrorStatsServiceAsyncClient, filename, *args, **kwargs) - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ErrorStatsServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ErrorStatsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ErrorStatsServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ErrorStatsServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ErrorStatsServiceTransport, - Callable[..., ErrorStatsServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the error stats service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ErrorStatsServiceTransport,Callable[..., ErrorStatsServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ErrorStatsServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ErrorStatsServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.devtools.clouderrorreporting_v1beta1.ErrorStatsServiceAsyncClient`.", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "universeDomain": getattr( - self._client._transport._credentials, "universe_domain", "" - ), - "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", - "credentialsInfo": getattr( - self.transport._credentials, "get_cred_info", lambda: None - )(), - } - if hasattr(self._client._transport, "_credentials") - else { - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "credentialsType": None, - }, - ) - - async def list_group_stats( - self, - request: Optional[ - Union[error_stats_service.ListGroupStatsRequest, dict] - ] = None, - *, - project_name: Optional[str] = None, - time_range: Optional[error_stats_service.QueryTimeRange] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListGroupStatsAsyncPager: - r"""Lists the specified groups. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import errorreporting_v1beta1 - - async def sample_list_group_stats(): - # Create a client - client = errorreporting_v1beta1.ErrorStatsServiceAsyncClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.ListGroupStatsRequest( - project_name="project_name_value", - ) - - # Make the request - page_result = client.list_group_stats(request=request) - - # Handle the response - async for response in page_result: - print(response) - - Args: - request (Optional[Union[google.cloud.errorreporting_v1beta1.types.ListGroupStatsRequest, dict]]): - 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/{projectID}`` or - ``projects/{projectNumber}``, where ``{projectID}`` and - ``{projectNumber}`` can be found in the `Google Cloud - console `__. - It may also include a location, such as - ``projects/{projectID}/locations/{location}`` where - ``{location}`` is a cloud region. - - Examples: ``projects/my-project-123``, - ``projects/5551234``, - ``projects/my-project-123/locations/us-central1``, - ``projects/5551234/locations/us-central1``. - - For a list of supported locations, see `Supported - Regions `__. - ``global`` is the default when unspecified. Use ``-`` as - a wildcard to request group stats from all regions. - - This corresponds to the ``project_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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] - [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsResponse.time_range_begin] - in the response will specify the beginning of this time - range. Only [ErrorGroupStats] - [google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats] - with a non-zero count in the given time range are - returned, unless the request contains an explicit - [group_id] - [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.group_id] - list. If a [group_id] - [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.group_id] - list is given, also [ErrorGroupStats] - [google.devtools.clouderrorreporting.v1beta1.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. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListGroupStatsAsyncPager: - Contains a set of requested error - group stats. - Iterating over this object will yield - results and resolve additional pages - automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [project_name, time_range] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, error_stats_service.ListGroupStatsRequest): - request = error_stats_service.ListGroupStatsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if project_name is not None: - request.project_name = project_name - if time_range is not None: - request.time_range = time_range - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_group_stats - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("project_name", request.project_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__aiter__` convenience method. - response = pagers.ListGroupStatsAsyncPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def list_events( - self, - request: Optional[Union[error_stats_service.ListEventsRequest, dict]] = None, - *, - project_name: Optional[str] = None, - group_id: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListEventsAsyncPager: - r"""Lists the specified events. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import errorreporting_v1beta1 - - async def sample_list_events(): - # Create a client - client = errorreporting_v1beta1.ErrorStatsServiceAsyncClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.ListEventsRequest( - project_name="project_name_value", - group_id="group_id_value", - ) - - # Make the request - page_result = client.list_events(request=request) - - # Handle the response - async for response in page_result: - print(response) - - Args: - request (Optional[Union[google.cloud.errorreporting_v1beta1.types.ListEventsRequest, dict]]): - 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/{projectID}`` or - ``projects/{projectID}/locations/{location}``, where - ``{projectID}`` is the `Google Cloud Platform project - ID `__ - and ``{location}`` is a Cloud region. - - Examples: ``projects/my-project-123``, - ``projects/my-project-123/locations/global``. - - For a list of supported locations, see `Supported - Regions `__. - ``global`` is the default when unspecified. - - 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. - The ``group_id`` is a unique identifier for a particular - error group. The identifier is derived from key parts of - the error-log content and is treated as Service Data. - For information about how Service Data is handled, see - `Google Cloud Privacy - Notice `__. - - This corresponds to the ``group_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListEventsAsyncPager: - Contains a set of requested error - events. - Iterating over this object will yield - results and resolve additional pages - automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [project_name, group_id] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, error_stats_service.ListEventsRequest): - request = error_stats_service.ListEventsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if project_name is not None: - request.project_name = project_name - if group_id is not None: - request.group_id = group_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_events - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("project_name", request.project_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__aiter__` convenience method. - response = pagers.ListEventsAsyncPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def delete_events( - self, - request: Optional[Union[error_stats_service.DeleteEventsRequest, dict]] = None, - *, - project_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> error_stats_service.DeleteEventsResponse: - r"""Deletes all error events of a given project. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import errorreporting_v1beta1 - - async def sample_delete_events(): - # Create a client - client = errorreporting_v1beta1.ErrorStatsServiceAsyncClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.DeleteEventsRequest( - project_name="project_name_value", - ) - - # Make the request - response = await client.delete_events(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[google.cloud.errorreporting_v1beta1.types.DeleteEventsRequest, dict]]): - 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/{projectID}`` or - ``projects/{projectID}/locations/{location}``, where - ``{projectID}`` is the `Google Cloud Platform project - ID `__ - and ``{location}`` is a Cloud region. - - Examples: ``projects/my-project-123``, - ``projects/my-project-123/locations/global``. - - For a list of supported locations, see `Supported - Regions `__. - ``global`` is the default when unspecified. - - This corresponds to the ``project_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud.errorreporting_v1beta1.types.DeleteEventsResponse: - Response message for deleting error - events. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [project_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, error_stats_service.DeleteEventsRequest): - request = error_stats_service.DeleteEventsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if project_name is not None: - request.project_name = project_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.delete_events - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("project_name", request.project_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ErrorStatsServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ErrorStatsServiceAsyncClient",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/client.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/client.py deleted file mode 100644 index c01492ae..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/client.py +++ /dev/null @@ -1,1192 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - Mapping, - MutableMapping, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.cloud.errorreporting_v1beta1 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - -from google.cloud.errorreporting_v1beta1.services.error_stats_service import pagers -from google.cloud.errorreporting_v1beta1.types import common -from google.cloud.errorreporting_v1beta1.types import error_stats_service -from .transports.base import ErrorStatsServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import ErrorStatsServiceGrpcTransport -from .transports.grpc_asyncio import ErrorStatsServiceGrpcAsyncIOTransport -from .transports.rest import ErrorStatsServiceRestTransport - - -class ErrorStatsServiceClientMeta(type): - """Metaclass for the ErrorStatsService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ErrorStatsServiceTransport]] - _transport_registry["grpc"] = ErrorStatsServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ErrorStatsServiceGrpcAsyncIOTransport - _transport_registry["rest"] = ErrorStatsServiceRestTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ErrorStatsServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ErrorStatsServiceClient(metaclass=ErrorStatsServiceClientMeta): - """An API for retrieving and managing error statistics as well - as data for individual events. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "clouderrorreporting.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "clouderrorreporting.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @staticmethod - def _use_client_cert_effective(): - """Returns whether client certificate should be used for mTLS if the - google-auth version supports should_use_client_cert automatic mTLS enablement. - - Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. - - Returns: - bool: whether client certificate should be used for mTLS - Raises: - ValueError: (If using a version of google-auth without should_use_client_cert and - GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) - """ - # check if google-auth version supports should_use_client_cert for automatic mTLS enablement - if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER - return mtls.should_use_client_cert() - else: # pragma: NO COVER - # if unsupported, fallback to reading from env var - use_client_cert_str = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - if use_client_cert_str not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" - " either `true` or `false`" - ) - return use_client_cert_str == "true" - - @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 - 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: - ErrorStatsServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file(filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ErrorStatsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ErrorStatsServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def error_group_path( - project: str, - group: str, - ) -> str: - """Returns a fully-qualified error_group string.""" - return "projects/{project}/groups/{group}".format( - project=project, - group=group, - ) - - @staticmethod - def parse_error_group_path(path: str) -> Dict[str, str]: - """Parses a error_group path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/groups/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = ErrorStatsServiceClient._use_client_cert_effective() - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert: - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = ErrorStatsServiceClient._use_client_cert_effective() - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert, use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ErrorStatsServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ErrorStatsServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ErrorStatsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], universe_domain_env: Optional[str] - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ErrorStatsServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ErrorStatsServiceTransport, - Callable[..., ErrorStatsServiceTransport], - ] - ] = None, - client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the error stats service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ErrorStatsServiceTransport,Callable[..., ErrorStatsServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ErrorStatsServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict(self._client_options) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr(self._client_options, "universe_domain", None) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ErrorStatsServiceClient._read_environment_variables() - self._client_cert_source = ErrorStatsServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - self._universe_domain = ErrorStatsServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # Initialize the universe domain validation. - self._is_universe_domain_valid = False - - if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER - # Setup logging. - client_logging.initialize_logging() - - api_key_value = getattr(self._client_options, "api_key", None) - if api_key_value and credentials: - raise ValueError( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, ErrorStatsServiceTransport) - if transport_provided: - # transport is a ErrorStatsServiceTransport instance. - if credentials or self._client_options.credentials_file or api_key_value: - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(ErrorStatsServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ErrorStatsServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ErrorStatsServiceTransport], - Callable[..., ErrorStatsServiceTransport], - ] = ( - ErrorStatsServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., ErrorStatsServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - api_audience=self._client_options.api_audience, - ) - - if "async" not in str(self._transport): - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.devtools.clouderrorreporting_v1beta1.ErrorStatsServiceClient`.", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "universeDomain": getattr( - self._transport._credentials, "universe_domain", "" - ), - "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", - "credentialsInfo": getattr( - self.transport._credentials, "get_cred_info", lambda: None - )(), - } - if hasattr(self._transport, "_credentials") - else { - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "credentialsType": None, - }, - ) - - def list_group_stats( - self, - request: Optional[ - Union[error_stats_service.ListGroupStatsRequest, dict] - ] = None, - *, - project_name: Optional[str] = None, - time_range: Optional[error_stats_service.QueryTimeRange] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListGroupStatsPager: - r"""Lists the specified groups. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import errorreporting_v1beta1 - - def sample_list_group_stats(): - # Create a client - client = errorreporting_v1beta1.ErrorStatsServiceClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.ListGroupStatsRequest( - project_name="project_name_value", - ) - - # Make the request - page_result = client.list_group_stats(request=request) - - # Handle the response - for response in page_result: - print(response) - - Args: - request (Union[google.cloud.errorreporting_v1beta1.types.ListGroupStatsRequest, dict]): - The request object. Specifies a set of ``ErrorGroupStats`` to return. - 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 `__. - It may also include a location, such as - ``projects/{projectID}/locations/{location}`` where - ``{location}`` is a cloud region. - - Examples: ``projects/my-project-123``, - ``projects/5551234``, - ``projects/my-project-123/locations/us-central1``, - ``projects/5551234/locations/us-central1``. - - For a list of supported locations, see `Supported - Regions `__. - ``global`` is the default when unspecified. Use ``-`` as - a wildcard to request group stats from all regions. - - This corresponds to the ``project_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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] - [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsResponse.time_range_begin] - in the response will specify the beginning of this time - range. Only [ErrorGroupStats] - [google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats] - with a non-zero count in the given time range are - returned, unless the request contains an explicit - [group_id] - [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.group_id] - list. If a [group_id] - [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.group_id] - list is given, also [ErrorGroupStats] - [google.devtools.clouderrorreporting.v1beta1.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. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListGroupStatsPager: - Contains a set of requested error - group stats. - Iterating over this object will yield - results and resolve additional pages - automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [project_name, time_range] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, error_stats_service.ListGroupStatsRequest): - request = error_stats_service.ListGroupStatsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if project_name is not None: - request.project_name = project_name - if time_range is not None: - request.time_range = time_range - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.list_group_stats] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("project_name", request.project_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.ListGroupStatsPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_events( - self, - request: Optional[Union[error_stats_service.ListEventsRequest, dict]] = None, - *, - project_name: Optional[str] = None, - group_id: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListEventsPager: - r"""Lists the specified events. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import errorreporting_v1beta1 - - def sample_list_events(): - # Create a client - client = errorreporting_v1beta1.ErrorStatsServiceClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.ListEventsRequest( - project_name="project_name_value", - group_id="group_id_value", - ) - - # Make the request - page_result = client.list_events(request=request) - - # Handle the response - for response in page_result: - print(response) - - Args: - request (Union[google.cloud.errorreporting_v1beta1.types.ListEventsRequest, dict]): - The request object. Specifies a set of error events to - return. - project_name (str): - Required. The resource name of the Google Cloud Platform - project. Written as ``projects/{projectID}`` or - ``projects/{projectID}/locations/{location}``, where - ``{projectID}`` is the `Google Cloud Platform project - ID `__ - and ``{location}`` is a Cloud region. - - Examples: ``projects/my-project-123``, - ``projects/my-project-123/locations/global``. - - For a list of supported locations, see `Supported - Regions `__. - ``global`` is the default when unspecified. - - This corresponds to the ``project_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - group_id (str): - Required. The group for which events shall be returned. - The ``group_id`` is a unique identifier for a particular - error group. The identifier is derived from key parts of - the error-log content and is treated as Service Data. - For information about how Service Data is handled, see - `Google Cloud Privacy - Notice `__. - - This corresponds to the ``group_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListEventsPager: - Contains a set of requested error - events. - Iterating over this object will yield - results and resolve additional pages - automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [project_name, group_id] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, error_stats_service.ListEventsRequest): - request = error_stats_service.ListEventsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if project_name is not None: - request.project_name = project_name - if group_id is not None: - request.group_id = group_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.list_events] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("project_name", request.project_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.ListEventsPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def delete_events( - self, - request: Optional[Union[error_stats_service.DeleteEventsRequest, dict]] = None, - *, - project_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> error_stats_service.DeleteEventsResponse: - r"""Deletes all error events of a given project. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import errorreporting_v1beta1 - - def sample_delete_events(): - # Create a client - client = errorreporting_v1beta1.ErrorStatsServiceClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.DeleteEventsRequest( - project_name="project_name_value", - ) - - # Make the request - response = client.delete_events(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud.errorreporting_v1beta1.types.DeleteEventsRequest, dict]): - The request object. Deletes all events in the project. - project_name (str): - Required. The resource name of the Google Cloud Platform - project. Written as ``projects/{projectID}`` or - ``projects/{projectID}/locations/{location}``, where - ``{projectID}`` is the `Google Cloud Platform project - ID `__ - and ``{location}`` is a Cloud region. - - Examples: ``projects/my-project-123``, - ``projects/my-project-123/locations/global``. - - For a list of supported locations, see `Supported - Regions `__. - ``global`` is the default when unspecified. - - This corresponds to the ``project_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud.errorreporting_v1beta1.types.DeleteEventsResponse: - Response message for deleting error - events. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [project_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, error_stats_service.DeleteEventsRequest): - request = error_stats_service.DeleteEventsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if project_name is not None: - request.project_name = project_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.delete_events] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("project_name", request.project_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ErrorStatsServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ErrorStatsServiceClient",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/pagers.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/pagers.py deleted file mode 100644 index 190fecd9..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/pagers.py +++ /dev/null @@ -1,353 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import retry_async as retries_async -from typing import ( - Any, - AsyncIterator, - Awaitable, - Callable, - Sequence, - Tuple, - Optional, - Iterator, - Union, -) - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] - OptionalAsyncRetry = Union[ - retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore - -from google.cloud.errorreporting_v1beta1.types import common -from google.cloud.errorreporting_v1beta1.types import error_stats_service - - -class ListGroupStatsPager: - """A pager for iterating through ``list_group_stats`` requests. - - This class thinly wraps an initial - :class:`google.cloud.errorreporting_v1beta1.types.ListGroupStatsResponse` object, and - provides an ``__iter__`` method to iterate through its - ``error_group_stats`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``ListGroupStats`` requests and continue to iterate - through the ``error_group_stats`` field on the - corresponding responses. - - 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. - """ - - def __init__( - self, - method: Callable[..., error_stats_service.ListGroupStatsResponse], - request: error_stats_service.ListGroupStatsRequest, - response: error_stats_service.ListGroupStatsResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = () - ): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.cloud.errorreporting_v1beta1.types.ListGroupStatsRequest): - The initial request object. - response (google.cloud.errorreporting_v1beta1.types.ListGroupStatsResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - """ - self._method = method - self._request = error_stats_service.ListGroupStatsRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[error_stats_service.ListGroupStatsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __iter__(self) -> Iterator[error_stats_service.ErrorGroupStats]: - for page in self.pages: - yield from page.error_group_stats - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) - - -class ListGroupStatsAsyncPager: - """A pager for iterating through ``list_group_stats`` requests. - - This class thinly wraps an initial - :class:`google.cloud.errorreporting_v1beta1.types.ListGroupStatsResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``error_group_stats`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``ListGroupStats`` requests and continue to iterate - through the ``error_group_stats`` field on the - corresponding responses. - - 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. - """ - - def __init__( - self, - method: Callable[..., Awaitable[error_stats_service.ListGroupStatsResponse]], - request: error_stats_service.ListGroupStatsRequest, - response: error_stats_service.ListGroupStatsResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = () - ): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.cloud.errorreporting_v1beta1.types.ListGroupStatsRequest): - The initial request object. - response (google.cloud.errorreporting_v1beta1.types.ListGroupStatsResponse): - The initial response object. - retry (google.api_core.retry.AsyncRetry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - """ - self._method = method - self._request = error_stats_service.ListGroupStatsRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages(self) -> AsyncIterator[error_stats_service.ListGroupStatsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = await self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __aiter__(self) -> AsyncIterator[error_stats_service.ErrorGroupStats]: - async def async_generator(): - async for page in self.pages: - for response in page.error_group_stats: - yield response - - return async_generator() - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) - - -class ListEventsPager: - """A pager for iterating through ``list_events`` requests. - - This class thinly wraps an initial - :class:`google.cloud.errorreporting_v1beta1.types.ListEventsResponse` object, and - provides an ``__iter__`` method to iterate through its - ``error_events`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``ListEvents`` requests and continue to iterate - through the ``error_events`` field on the - corresponding responses. - - 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. - """ - - def __init__( - self, - method: Callable[..., error_stats_service.ListEventsResponse], - request: error_stats_service.ListEventsRequest, - response: error_stats_service.ListEventsResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = () - ): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.cloud.errorreporting_v1beta1.types.ListEventsRequest): - The initial request object. - response (google.cloud.errorreporting_v1beta1.types.ListEventsResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - """ - self._method = method - self._request = error_stats_service.ListEventsRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[error_stats_service.ListEventsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __iter__(self) -> Iterator[common.ErrorEvent]: - for page in self.pages: - yield from page.error_events - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) - - -class ListEventsAsyncPager: - """A pager for iterating through ``list_events`` requests. - - This class thinly wraps an initial - :class:`google.cloud.errorreporting_v1beta1.types.ListEventsResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``error_events`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``ListEvents`` requests and continue to iterate - through the ``error_events`` field on the - corresponding responses. - - 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. - """ - - def __init__( - self, - method: Callable[..., Awaitable[error_stats_service.ListEventsResponse]], - request: error_stats_service.ListEventsRequest, - response: error_stats_service.ListEventsResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = () - ): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.cloud.errorreporting_v1beta1.types.ListEventsRequest): - The initial request object. - response (google.cloud.errorreporting_v1beta1.types.ListEventsResponse): - The initial response object. - retry (google.api_core.retry.AsyncRetry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - """ - self._method = method - self._request = error_stats_service.ListEventsRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages(self) -> AsyncIterator[error_stats_service.ListEventsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = await self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __aiter__(self) -> AsyncIterator[common.ErrorEvent]: - async def async_generator(): - async for page in self.pages: - for response in page.error_events: - yield response - - return async_generator() - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/README.rst b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/README.rst deleted file mode 100644 index 9fb4cf06..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/README.rst +++ /dev/null @@ -1,9 +0,0 @@ - -transport inheritance structure -_______________________________ - -`ErrorStatsServiceTransport` is the ABC for all transports. -- public child `ErrorStatsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). -- public child `ErrorStatsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). -- private child `_BaseErrorStatsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). -- public child `ErrorStatsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/__init__.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/__init__.py deleted file mode 100644 index 8f452e45..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/__init__.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from typing import Dict, Type - -from .base import ErrorStatsServiceTransport -from .grpc import ErrorStatsServiceGrpcTransport -from .grpc_asyncio import ErrorStatsServiceGrpcAsyncIOTransport -from .rest import ErrorStatsServiceRestTransport -from .rest import ErrorStatsServiceRestInterceptor - - -# Compile a registry of transports. -_transport_registry = OrderedDict() # type: Dict[str, Type[ErrorStatsServiceTransport]] -_transport_registry["grpc"] = ErrorStatsServiceGrpcTransport -_transport_registry["grpc_asyncio"] = ErrorStatsServiceGrpcAsyncIOTransport -_transport_registry["rest"] = ErrorStatsServiceRestTransport - -__all__ = ( - "ErrorStatsServiceTransport", - "ErrorStatsServiceGrpcTransport", - "ErrorStatsServiceGrpcAsyncIOTransport", - "ErrorStatsServiceRestTransport", - "ErrorStatsServiceRestInterceptor", -) 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 deleted file mode 100644 index 8d5312e3..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/base.py +++ /dev/null @@ -1,207 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Dict, Optional, Sequence, Union - -from google.cloud.errorreporting_v1beta1 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.cloud.errorreporting_v1beta1.types import error_stats_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ErrorStatsServiceTransport(abc.ABC): - """Abstract transport class for ErrorStatsService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) - - DEFAULT_HOST: str = "clouderrorreporting.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. This argument will be - removed in the next major version of this library. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - default_scopes=self.AUTH_SCOPES, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - scopes=scopes, - quota_project_id=quota_project_id, - default_scopes=self.AUTH_SCOPES, - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr(service_account.Credentials, "with_always_use_jwt_access") - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.list_group_stats: gapic_v1.method.wrap_method( - self.list_group_stats, - default_timeout=None, - client_info=client_info, - ), - self.list_events: gapic_v1.method.wrap_method( - self.list_events, - default_timeout=None, - client_info=client_info, - ), - self.delete_events: gapic_v1.method.wrap_method( - self.delete_events, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def list_group_stats( - self, - ) -> Callable[ - [error_stats_service.ListGroupStatsRequest], - Union[ - error_stats_service.ListGroupStatsResponse, - Awaitable[error_stats_service.ListGroupStatsResponse], - ], - ]: - raise NotImplementedError() - - @property - def list_events( - self, - ) -> Callable[ - [error_stats_service.ListEventsRequest], - Union[ - error_stats_service.ListEventsResponse, - Awaitable[error_stats_service.ListEventsResponse], - ], - ]: - raise NotImplementedError() - - @property - def delete_events( - self, - ) -> Callable[ - [error_stats_service.DeleteEventsRequest], - Union[ - error_stats_service.DeleteEventsResponse, - Awaitable[error_stats_service.DeleteEventsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ErrorStatsServiceTransport",) 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 deleted file mode 100644 index 244aba2d..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc.py +++ /dev/null @@ -1,420 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import json -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -import google.auth # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore - -from google.cloud.errorreporting_v1beta1.types import error_stats_service -from .base import ErrorStatsServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" - - request_metadata = { - key: value.decode("utf-8") if isinstance(value, bytes) else value - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "rpcName": str(client_call_details.method), - "request": grpc_request, - "metadata": grpc_request["metadata"], - }, - ) - response = continuation(client_call_details, request) - if logging_enabled: # pragma: NO COVER - response_metadata = response.trailing_metadata() - # Convert gRPC metadata `` to list of tuples - metadata = ( - dict([(k, str(v)) for k, v in response_metadata]) - if response_metadata - else None - ) - result = response.result() - if isinstance(result, proto.Message): - response_payload = type(result).to_json(result) - elif isinstance(result, google.protobuf.message.Message): - response_payload = MessageToJson(result) - else: - response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" - grpc_response = { - "payload": response_payload, - "metadata": metadata, - "status": "OK", - } - _LOGGER.debug( - f"Received response for {client_call_details.method}.", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ErrorStatsServiceGrpcTransport(ErrorStatsServiceTransport): - """gRPC backend transport for ErrorStatsService. - - An API for retrieving and managing error statistics as well - as data for individual events. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - This argument will be removed in the next major version of this library. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - self._interceptor = _LoggingClientInterceptor() - self._logged_channel = grpc.intercept_channel( - self._grpc_channel, self._interceptor - ) - - # Wrap messages. This must be done after self._logged_channel exists - self._prep_wrapped_messages(client_info) - - @classmethod - def create_channel( - cls, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. This argument will be - removed in the next major version of this library. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def list_group_stats( - self, - ) -> Callable[ - [error_stats_service.ListGroupStatsRequest], - error_stats_service.ListGroupStatsResponse, - ]: - r"""Return a callable for the list group stats method over gRPC. - - Lists the specified groups. - - Returns: - Callable[[~.ListGroupStatsRequest], - ~.ListGroupStatsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_group_stats" not in self._stubs: - self._stubs["list_group_stats"] = self._logged_channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/ListGroupStats", - request_serializer=error_stats_service.ListGroupStatsRequest.serialize, - response_deserializer=error_stats_service.ListGroupStatsResponse.deserialize, - ) - return self._stubs["list_group_stats"] - - @property - def list_events( - self, - ) -> Callable[ - [error_stats_service.ListEventsRequest], error_stats_service.ListEventsResponse - ]: - r"""Return a callable for the list events method over gRPC. - - Lists the specified events. - - Returns: - Callable[[~.ListEventsRequest], - ~.ListEventsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_events" not in self._stubs: - self._stubs["list_events"] = self._logged_channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/ListEvents", - request_serializer=error_stats_service.ListEventsRequest.serialize, - response_deserializer=error_stats_service.ListEventsResponse.deserialize, - ) - return self._stubs["list_events"] - - @property - def delete_events( - self, - ) -> Callable[ - [error_stats_service.DeleteEventsRequest], - error_stats_service.DeleteEventsResponse, - ]: - r"""Return a callable for the delete events method over gRPC. - - Deletes all error events of a given project. - - Returns: - Callable[[~.DeleteEventsRequest], - ~.DeleteEventsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "delete_events" not in self._stubs: - self._stubs["delete_events"] = self._logged_channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/DeleteEvents", - request_serializer=error_stats_service.DeleteEventsRequest.serialize, - response_deserializer=error_stats_service.DeleteEventsResponse.deserialize, - ) - return self._stubs["delete_events"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ErrorStatsServiceGrpcTransport",) 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 deleted file mode 100644 index 892bf1e0..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,454 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import json -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.api_core import exceptions as core_exceptions -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.cloud.errorreporting_v1beta1.types import error_stats_service -from .base import ErrorStatsServiceTransport, DEFAULT_CLIENT_INFO -from .grpc import ErrorStatsServiceGrpcTransport - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientAIOInterceptor( - grpc.aio.UnaryUnaryClientInterceptor -): # pragma: NO COVER - async def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" - - request_metadata = { - key: value.decode("utf-8") if isinstance(value, bytes) else value - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "rpcName": str(client_call_details.method), - "request": grpc_request, - "metadata": grpc_request["metadata"], - }, - ) - response = await continuation(client_call_details, request) - if logging_enabled: # pragma: NO COVER - response_metadata = await response.trailing_metadata() - # Convert gRPC metadata `` to list of tuples - metadata = ( - dict([(k, str(v)) for k, v in response_metadata]) - if response_metadata - else None - ) - result = await response - if isinstance(result, proto.Message): - response_payload = type(result).to_json(result) - elif isinstance(result, google.protobuf.message.Message): - response_payload = MessageToJson(result) - else: - response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" - grpc_response = { - "payload": response_payload, - "metadata": metadata, - "status": "OK", - } - _LOGGER.debug( - f"Received response to rpc {client_call_details.method}.", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ErrorStatsServiceGrpcAsyncIOTransport(ErrorStatsServiceTransport): - """gRPC AsyncIO backend transport for ErrorStatsService. - - An API for retrieving and managing error statistics as well - as data for individual events. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be - removed in the next major version of this library. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - This argument will be removed in the next major version of this library. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - self._interceptor = _LoggingClientAIOInterceptor() - self._grpc_channel._unary_unary_interceptors.append(self._interceptor) - self._logged_channel = self._grpc_channel - self._wrap_with_kind = ( - "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters - ) - # Wrap messages. This must be done after self._logged_channel exists - self._prep_wrapped_messages(client_info) - - @property - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def list_group_stats( - self, - ) -> Callable[ - [error_stats_service.ListGroupStatsRequest], - Awaitable[error_stats_service.ListGroupStatsResponse], - ]: - r"""Return a callable for the list group stats method over gRPC. - - Lists the specified groups. - - Returns: - Callable[[~.ListGroupStatsRequest], - Awaitable[~.ListGroupStatsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_group_stats" not in self._stubs: - self._stubs["list_group_stats"] = self._logged_channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/ListGroupStats", - request_serializer=error_stats_service.ListGroupStatsRequest.serialize, - response_deserializer=error_stats_service.ListGroupStatsResponse.deserialize, - ) - return self._stubs["list_group_stats"] - - @property - def list_events( - self, - ) -> Callable[ - [error_stats_service.ListEventsRequest], - Awaitable[error_stats_service.ListEventsResponse], - ]: - r"""Return a callable for the list events method over gRPC. - - Lists the specified events. - - Returns: - Callable[[~.ListEventsRequest], - Awaitable[~.ListEventsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_events" not in self._stubs: - self._stubs["list_events"] = self._logged_channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/ListEvents", - request_serializer=error_stats_service.ListEventsRequest.serialize, - response_deserializer=error_stats_service.ListEventsResponse.deserialize, - ) - return self._stubs["list_events"] - - @property - def delete_events( - self, - ) -> Callable[ - [error_stats_service.DeleteEventsRequest], - Awaitable[error_stats_service.DeleteEventsResponse], - ]: - r"""Return a callable for the delete events method over gRPC. - - Deletes all error events of a given project. - - Returns: - Callable[[~.DeleteEventsRequest], - Awaitable[~.DeleteEventsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "delete_events" not in self._stubs: - self._stubs["delete_events"] = self._logged_channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ErrorStatsService/DeleteEvents", - request_serializer=error_stats_service.DeleteEventsRequest.serialize, - response_deserializer=error_stats_service.DeleteEventsResponse.deserialize, - ) - return self._stubs["delete_events"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.list_group_stats: self._wrap_method( - self.list_group_stats, - default_timeout=None, - client_info=client_info, - ), - self.list_events: self._wrap_method( - self.list_events, - default_timeout=None, - client_info=client_info, - ), - self.delete_events: self._wrap_method( - self.delete_events, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ErrorStatsServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/rest.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/rest.py deleted file mode 100644 index 52bde4cd..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/rest.py +++ /dev/null @@ -1,841 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -import json # type: ignore - -from google.auth.transport.requests import AuthorizedSession # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -from google.api_core import rest_helpers -from google.api_core import rest_streaming -from google.api_core import gapic_v1 -import google.protobuf - -from google.protobuf import json_format - -from requests import __version__ as requests_version -import dataclasses -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union -import warnings - - -from google.cloud.errorreporting_v1beta1.types import error_stats_service - - -from .rest_base import _BaseErrorStatsServiceRestTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = logging.getLogger(__name__) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, - grpc_version=None, - rest_version=f"requests@{requests_version}", -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ErrorStatsServiceRestInterceptor: - """Interceptor for ErrorStatsService. - - Interceptors are used to manipulate requests, request metadata, and responses - in arbitrary ways. - Example use cases include: - * Logging - * Verifying requests according to service or custom semantics - * Stripping extraneous information from responses - - These use cases and more can be enabled by injecting an - instance of a custom subclass when constructing the ErrorStatsServiceRestTransport. - - .. code-block:: python - class MyCustomErrorStatsServiceInterceptor(ErrorStatsServiceRestInterceptor): - def pre_delete_events(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_delete_events(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_list_events(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_list_events(self, response): - logging.log(f"Received response: {response}") - return response - - def pre_list_group_stats(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_list_group_stats(self, response): - logging.log(f"Received response: {response}") - return response - - transport = ErrorStatsServiceRestTransport(interceptor=MyCustomErrorStatsServiceInterceptor()) - client = ErrorStatsServiceClient(transport=transport) - - - """ - - def pre_delete_events( - self, - request: error_stats_service.DeleteEventsRequest, - metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - error_stats_service.DeleteEventsRequest, Sequence[Tuple[str, Union[str, bytes]]] - ]: - """Pre-rpc interceptor for delete_events - - Override in a subclass to manipulate the request or metadata - before they are sent to the ErrorStatsService server. - """ - return request, metadata - - def post_delete_events( - self, response: error_stats_service.DeleteEventsResponse - ) -> error_stats_service.DeleteEventsResponse: - """Post-rpc interceptor for delete_events - - DEPRECATED. Please use the `post_delete_events_with_metadata` - interceptor instead. - - Override in a subclass to read or manipulate the response - after it is returned by the ErrorStatsService server but before - it is returned to user code. This `post_delete_events` interceptor runs - before the `post_delete_events_with_metadata` interceptor. - """ - return response - - def post_delete_events_with_metadata( - self, - response: error_stats_service.DeleteEventsResponse, - metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - error_stats_service.DeleteEventsResponse, - Sequence[Tuple[str, Union[str, bytes]]], - ]: - """Post-rpc interceptor for delete_events - - Override in a subclass to read or manipulate the response or metadata after it - is returned by the ErrorStatsService server but before it is returned to user code. - - We recommend only using this `post_delete_events_with_metadata` - interceptor in new development instead of the `post_delete_events` interceptor. - When both interceptors are used, this `post_delete_events_with_metadata` interceptor runs after the - `post_delete_events` interceptor. The (possibly modified) response returned by - `post_delete_events` will be passed to - `post_delete_events_with_metadata`. - """ - return response, metadata - - def pre_list_events( - self, - request: error_stats_service.ListEventsRequest, - metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - error_stats_service.ListEventsRequest, Sequence[Tuple[str, Union[str, bytes]]] - ]: - """Pre-rpc interceptor for list_events - - Override in a subclass to manipulate the request or metadata - before they are sent to the ErrorStatsService server. - """ - return request, metadata - - def post_list_events( - self, response: error_stats_service.ListEventsResponse - ) -> error_stats_service.ListEventsResponse: - """Post-rpc interceptor for list_events - - DEPRECATED. Please use the `post_list_events_with_metadata` - interceptor instead. - - Override in a subclass to read or manipulate the response - after it is returned by the ErrorStatsService server but before - it is returned to user code. This `post_list_events` interceptor runs - before the `post_list_events_with_metadata` interceptor. - """ - return response - - def post_list_events_with_metadata( - self, - response: error_stats_service.ListEventsResponse, - metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - error_stats_service.ListEventsResponse, Sequence[Tuple[str, Union[str, bytes]]] - ]: - """Post-rpc interceptor for list_events - - Override in a subclass to read or manipulate the response or metadata after it - is returned by the ErrorStatsService server but before it is returned to user code. - - We recommend only using this `post_list_events_with_metadata` - interceptor in new development instead of the `post_list_events` interceptor. - When both interceptors are used, this `post_list_events_with_metadata` interceptor runs after the - `post_list_events` interceptor. The (possibly modified) response returned by - `post_list_events` will be passed to - `post_list_events_with_metadata`. - """ - return response, metadata - - def pre_list_group_stats( - self, - request: error_stats_service.ListGroupStatsRequest, - metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - error_stats_service.ListGroupStatsRequest, - Sequence[Tuple[str, Union[str, bytes]]], - ]: - """Pre-rpc interceptor for list_group_stats - - Override in a subclass to manipulate the request or metadata - before they are sent to the ErrorStatsService server. - """ - return request, metadata - - def post_list_group_stats( - self, response: error_stats_service.ListGroupStatsResponse - ) -> error_stats_service.ListGroupStatsResponse: - """Post-rpc interceptor for list_group_stats - - DEPRECATED. Please use the `post_list_group_stats_with_metadata` - interceptor instead. - - Override in a subclass to read or manipulate the response - after it is returned by the ErrorStatsService server but before - it is returned to user code. This `post_list_group_stats` interceptor runs - before the `post_list_group_stats_with_metadata` interceptor. - """ - return response - - def post_list_group_stats_with_metadata( - self, - response: error_stats_service.ListGroupStatsResponse, - metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - error_stats_service.ListGroupStatsResponse, - Sequence[Tuple[str, Union[str, bytes]]], - ]: - """Post-rpc interceptor for list_group_stats - - Override in a subclass to read or manipulate the response or metadata after it - is returned by the ErrorStatsService server but before it is returned to user code. - - We recommend only using this `post_list_group_stats_with_metadata` - interceptor in new development instead of the `post_list_group_stats` interceptor. - When both interceptors are used, this `post_list_group_stats_with_metadata` interceptor runs after the - `post_list_group_stats` interceptor. The (possibly modified) response returned by - `post_list_group_stats` will be passed to - `post_list_group_stats_with_metadata`. - """ - return response, metadata - - -@dataclasses.dataclass -class ErrorStatsServiceRestStub: - _session: AuthorizedSession - _host: str - _interceptor: ErrorStatsServiceRestInterceptor - - -class ErrorStatsServiceRestTransport(_BaseErrorStatsServiceRestTransport): - """REST backend synchronous transport for ErrorStatsService. - - An API for retrieving and managing error statistics as well - as data for individual events. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends JSON representations of protocol buffers over HTTP/1.1 - """ - - def __init__( - self, - *, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - url_scheme: str = "https", - interceptor: Optional[ErrorStatsServiceRestInterceptor] = None, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. This argument will be - removed in the next major version of this library. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if ``channel`` is provided. - client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client - certificate to configure mutual TLS HTTP channel. It is ignored - if ``channel`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you are developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - url_scheme: the protocol scheme for the API endpoint. Normally - "https", but for testing or local servers, - "http" can be specified. - """ - # Run the base constructor - # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. - # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the - # credentials object - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - url_scheme=url_scheme, - api_audience=api_audience, - ) - self._session = AuthorizedSession( - self._credentials, default_host=self.DEFAULT_HOST - ) - if client_cert_source_for_mtls: - self._session.configure_mtls_channel(client_cert_source_for_mtls) - self._interceptor = interceptor or ErrorStatsServiceRestInterceptor() - self._prep_wrapped_messages(client_info) - - class _DeleteEvents( - _BaseErrorStatsServiceRestTransport._BaseDeleteEvents, ErrorStatsServiceRestStub - ): - def __hash__(self): - return hash("ErrorStatsServiceRestTransport.DeleteEvents") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None, - ): - uri = transcoded_request["uri"] - method = transcoded_request["method"] - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__( - self, - request: error_stats_service.DeleteEventsRequest, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> error_stats_service.DeleteEventsResponse: - r"""Call the delete events method over HTTP. - - Args: - request (~.error_stats_service.DeleteEventsRequest): - The request object. Deletes all events in the project. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - ~.error_stats_service.DeleteEventsResponse: - Response message for deleting error - events. - - """ - - http_options = ( - _BaseErrorStatsServiceRestTransport._BaseDeleteEvents._get_http_options() - ) - - request, metadata = self._interceptor.pre_delete_events(request, metadata) - transcoded_request = _BaseErrorStatsServiceRestTransport._BaseDeleteEvents._get_transcoded_request( - http_options, request - ) - - # Jsonify the query params - query_params = _BaseErrorStatsServiceRestTransport._BaseDeleteEvents._get_query_params_json( - transcoded_request - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - logging.DEBUG - ): # pragma: NO COVER - request_url = "{host}{uri}".format( - host=self._host, uri=transcoded_request["uri"] - ) - method = transcoded_request["method"] - try: - request_payload = type(request).to_json(request) - except: - request_payload = None - http_request = { - "payload": request_payload, - "requestMethod": method, - "requestUrl": request_url, - "headers": dict(metadata), - } - _LOGGER.debug( - f"Sending request for google.devtools.clouderrorreporting_v1beta1.ErrorStatsServiceClient.DeleteEvents", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "rpcName": "DeleteEvents", - "httpRequest": http_request, - "metadata": http_request["headers"], - }, - ) - - # Send the request - response = ErrorStatsServiceRestTransport._DeleteEvents._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - ) - - # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception - # subclass. - if response.status_code >= 400: - raise core_exceptions.from_http_response(response) - - # Return the response - resp = error_stats_service.DeleteEventsResponse() - pb_resp = error_stats_service.DeleteEventsResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - - resp = self._interceptor.post_delete_events(resp) - response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_delete_events_with_metadata( - resp, response_metadata - ) - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - logging.DEBUG - ): # pragma: NO COVER - try: - response_payload = error_stats_service.DeleteEventsResponse.to_json( - response - ) - except: - response_payload = None - http_response = { - "payload": response_payload, - "headers": dict(response.headers), - "status": response.status_code, - } - _LOGGER.debug( - "Received response for google.devtools.clouderrorreporting_v1beta1.ErrorStatsServiceClient.delete_events", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "rpcName": "DeleteEvents", - "metadata": http_response["headers"], - "httpResponse": http_response, - }, - ) - return resp - - class _ListEvents( - _BaseErrorStatsServiceRestTransport._BaseListEvents, ErrorStatsServiceRestStub - ): - def __hash__(self): - return hash("ErrorStatsServiceRestTransport.ListEvents") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None, - ): - uri = transcoded_request["uri"] - method = transcoded_request["method"] - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__( - self, - request: error_stats_service.ListEventsRequest, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> error_stats_service.ListEventsResponse: - r"""Call the list events method over HTTP. - - Args: - request (~.error_stats_service.ListEventsRequest): - The request object. Specifies a set of error events to - return. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - ~.error_stats_service.ListEventsResponse: - Contains a set of requested error - events. - - """ - - http_options = ( - _BaseErrorStatsServiceRestTransport._BaseListEvents._get_http_options() - ) - - request, metadata = self._interceptor.pre_list_events(request, metadata) - transcoded_request = _BaseErrorStatsServiceRestTransport._BaseListEvents._get_transcoded_request( - http_options, request - ) - - # Jsonify the query params - query_params = _BaseErrorStatsServiceRestTransport._BaseListEvents._get_query_params_json( - transcoded_request - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - logging.DEBUG - ): # pragma: NO COVER - request_url = "{host}{uri}".format( - host=self._host, uri=transcoded_request["uri"] - ) - method = transcoded_request["method"] - try: - request_payload = type(request).to_json(request) - except: - request_payload = None - http_request = { - "payload": request_payload, - "requestMethod": method, - "requestUrl": request_url, - "headers": dict(metadata), - } - _LOGGER.debug( - f"Sending request for google.devtools.clouderrorreporting_v1beta1.ErrorStatsServiceClient.ListEvents", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "rpcName": "ListEvents", - "httpRequest": http_request, - "metadata": http_request["headers"], - }, - ) - - # Send the request - response = ErrorStatsServiceRestTransport._ListEvents._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - ) - - # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception - # subclass. - if response.status_code >= 400: - raise core_exceptions.from_http_response(response) - - # Return the response - resp = error_stats_service.ListEventsResponse() - pb_resp = error_stats_service.ListEventsResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - - resp = self._interceptor.post_list_events(resp) - response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_events_with_metadata( - resp, response_metadata - ) - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - logging.DEBUG - ): # pragma: NO COVER - try: - response_payload = error_stats_service.ListEventsResponse.to_json( - response - ) - except: - response_payload = None - http_response = { - "payload": response_payload, - "headers": dict(response.headers), - "status": response.status_code, - } - _LOGGER.debug( - "Received response for google.devtools.clouderrorreporting_v1beta1.ErrorStatsServiceClient.list_events", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "rpcName": "ListEvents", - "metadata": http_response["headers"], - "httpResponse": http_response, - }, - ) - return resp - - class _ListGroupStats( - _BaseErrorStatsServiceRestTransport._BaseListGroupStats, - ErrorStatsServiceRestStub, - ): - def __hash__(self): - return hash("ErrorStatsServiceRestTransport.ListGroupStats") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None, - ): - uri = transcoded_request["uri"] - method = transcoded_request["method"] - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - ) - return response - - def __call__( - self, - request: error_stats_service.ListGroupStatsRequest, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> error_stats_service.ListGroupStatsResponse: - r"""Call the list group stats method over HTTP. - - Args: - request (~.error_stats_service.ListGroupStatsRequest): - The request object. Specifies a set of ``ErrorGroupStats`` to return. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - ~.error_stats_service.ListGroupStatsResponse: - Contains a set of requested error - group stats. - - """ - - http_options = ( - _BaseErrorStatsServiceRestTransport._BaseListGroupStats._get_http_options() - ) - - request, metadata = self._interceptor.pre_list_group_stats( - request, metadata - ) - transcoded_request = _BaseErrorStatsServiceRestTransport._BaseListGroupStats._get_transcoded_request( - http_options, request - ) - - # Jsonify the query params - query_params = _BaseErrorStatsServiceRestTransport._BaseListGroupStats._get_query_params_json( - transcoded_request - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - logging.DEBUG - ): # pragma: NO COVER - request_url = "{host}{uri}".format( - host=self._host, uri=transcoded_request["uri"] - ) - method = transcoded_request["method"] - try: - request_payload = type(request).to_json(request) - except: - request_payload = None - http_request = { - "payload": request_payload, - "requestMethod": method, - "requestUrl": request_url, - "headers": dict(metadata), - } - _LOGGER.debug( - f"Sending request for google.devtools.clouderrorreporting_v1beta1.ErrorStatsServiceClient.ListGroupStats", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "rpcName": "ListGroupStats", - "httpRequest": http_request, - "metadata": http_request["headers"], - }, - ) - - # Send the request - response = ErrorStatsServiceRestTransport._ListGroupStats._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - ) - - # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception - # subclass. - if response.status_code >= 400: - raise core_exceptions.from_http_response(response) - - # Return the response - resp = error_stats_service.ListGroupStatsResponse() - pb_resp = error_stats_service.ListGroupStatsResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - - resp = self._interceptor.post_list_group_stats(resp) - response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_list_group_stats_with_metadata( - resp, response_metadata - ) - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - logging.DEBUG - ): # pragma: NO COVER - try: - response_payload = ( - error_stats_service.ListGroupStatsResponse.to_json(response) - ) - except: - response_payload = None - http_response = { - "payload": response_payload, - "headers": dict(response.headers), - "status": response.status_code, - } - _LOGGER.debug( - "Received response for google.devtools.clouderrorreporting_v1beta1.ErrorStatsServiceClient.list_group_stats", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "rpcName": "ListGroupStats", - "metadata": http_response["headers"], - "httpResponse": http_response, - }, - ) - return resp - - @property - def delete_events( - self, - ) -> Callable[ - [error_stats_service.DeleteEventsRequest], - error_stats_service.DeleteEventsResponse, - ]: - # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. - # In C++ this would require a dynamic_cast - return self._DeleteEvents(self._session, self._host, self._interceptor) # type: ignore - - @property - def list_events( - self, - ) -> Callable[ - [error_stats_service.ListEventsRequest], error_stats_service.ListEventsResponse - ]: - # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. - # In C++ this would require a dynamic_cast - return self._ListEvents(self._session, self._host, self._interceptor) # type: ignore - - @property - def list_group_stats( - self, - ) -> Callable[ - [error_stats_service.ListGroupStatsRequest], - error_stats_service.ListGroupStatsResponse, - ]: - # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. - # In C++ this would require a dynamic_cast - return self._ListGroupStats(self._session, self._host, self._interceptor) # type: ignore - - @property - def kind(self) -> str: - return "rest" - - def close(self): - self._session.close() - - -__all__ = ("ErrorStatsServiceRestTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/rest_base.py b/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/rest_base.py deleted file mode 100644 index 77269984..00000000 --- a/google/cloud/errorreporting_v1beta1/services/error_stats_service/transports/rest_base.py +++ /dev/null @@ -1,248 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import json # type: ignore -from google.api_core import path_template -from google.api_core import gapic_v1 - -from google.protobuf import json_format -from .base import ErrorStatsServiceTransport, DEFAULT_CLIENT_INFO - -import re -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union - - -from google.cloud.errorreporting_v1beta1.types import error_stats_service - - -class _BaseErrorStatsServiceRestTransport(ErrorStatsServiceTransport): - """Base REST backend transport for ErrorStatsService. - - Note: This class is not meant to be used directly. Use its sync and - async sub-classes instead. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends JSON representations of protocol buffers over HTTP/1.1 - """ - - def __init__( - self, - *, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[Any] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - url_scheme: str = "https", - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[Any]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you are developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - url_scheme: the protocol scheme for the API endpoint. Normally - "https", but for testing or local servers, - "http" can be specified. - """ - # Run the base constructor - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - class _BaseDeleteEvents: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [ - { - "method": "delete", - "uri": "/v1beta1/{project_name=projects/*}/events", - }, - { - "method": "delete", - "uri": "/v1beta1/{project_name=projects/*/locations/*}/events", - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = error_stats_service.DeleteEventsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) - ) - query_params.update( - _BaseErrorStatsServiceRestTransport._BaseDeleteEvents._get_unset_required_fields( - query_params - ) - ) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseListEvents: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "groupId": "", - } - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1beta1/{project_name=projects/*}/events", - }, - { - "method": "get", - "uri": "/v1beta1/{project_name=projects/*/locations/*}/events", - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = error_stats_service.ListEventsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) - ) - query_params.update( - _BaseErrorStatsServiceRestTransport._BaseListEvents._get_unset_required_fields( - query_params - ) - ) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - class _BaseListGroupStats: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [ - { - "method": "get", - "uri": "/v1beta1/{project_name=projects/*}/groupStats", - }, - { - "method": "get", - "uri": "/v1beta1/{project_name=projects/*/locations/*}/groupStats", - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = error_stats_service.ListGroupStatsRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) - ) - query_params.update( - _BaseErrorStatsServiceRestTransport._BaseListGroupStats._get_unset_required_fields( - query_params - ) - ) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - -__all__ = ("_BaseErrorStatsServiceRestTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/__init__.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/__init__.py deleted file mode 100644 index 2e3c1322..00000000 --- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .client import ReportErrorsServiceClient -from .async_client import ReportErrorsServiceAsyncClient - -__all__ = ( - "ReportErrorsServiceClient", - "ReportErrorsServiceAsyncClient", -) 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 deleted file mode 100644 index d91c885b..00000000 --- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/async_client.py +++ /dev/null @@ -1,467 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from collections import OrderedDict -import re -from typing import ( - Dict, - Callable, - Mapping, - MutableMapping, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, -) - -from google.cloud.errorreporting_v1beta1 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.cloud.errorreporting_v1beta1.types import report_errors_service -from .transports.base import ReportErrorsServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc_asyncio import ReportErrorsServiceGrpcAsyncIOTransport -from .client import ReportErrorsServiceClient - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class ReportErrorsServiceAsyncClient: - """An API for reporting error events.""" - - _client: ReportErrorsServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ReportErrorsServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ReportErrorsServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ReportErrorsServiceClient._DEFAULT_ENDPOINT_TEMPLATE - _DEFAULT_UNIVERSE = ReportErrorsServiceClient._DEFAULT_UNIVERSE - - common_billing_account_path = staticmethod( - ReportErrorsServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ReportErrorsServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(ReportErrorsServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - ReportErrorsServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ReportErrorsServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ReportErrorsServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod(ReportErrorsServiceClient.common_project_path) - parse_common_project_path = staticmethod( - ReportErrorsServiceClient.parse_common_project_path - ) - common_location_path = staticmethod(ReportErrorsServiceClient.common_location_path) - parse_common_location_path = staticmethod( - ReportErrorsServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ReportErrorsServiceAsyncClient: The constructed client. - """ - sa_info_func = ( - ReportErrorsServiceClient.from_service_account_info.__func__ # type: ignore - ) - return sa_info_func(ReportErrorsServiceAsyncClient, info, *args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ReportErrorsServiceAsyncClient: The constructed client. - """ - sa_file_func = ( - ReportErrorsServiceClient.from_service_account_file.__func__ # type: ignore - ) - return sa_file_func(ReportErrorsServiceAsyncClient, filename, *args, **kwargs) - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ReportErrorsServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ReportErrorsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ReportErrorsServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ReportErrorsServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ReportErrorsServiceTransport, - Callable[..., ReportErrorsServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the report errors service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ReportErrorsServiceTransport,Callable[..., ReportErrorsServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ReportErrorsServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ReportErrorsServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.devtools.clouderrorreporting_v1beta1.ReportErrorsServiceAsyncClient`.", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - "universeDomain": getattr( - self._client._transport._credentials, "universe_domain", "" - ), - "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}", - "credentialsInfo": getattr( - self.transport._credentials, "get_cred_info", lambda: None - )(), - } - if hasattr(self._client._transport, "_credentials") - else { - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - "credentialsType": None, - }, - ) - - async def report_error_event( - self, - request: Optional[ - Union[report_errors_service.ReportErrorEventRequest, dict] - ] = None, - *, - project_name: Optional[str] = None, - event: Optional[report_errors_service.ReportedErrorEvent] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> report_errors_service.ReportErrorEventResponse: - 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/{projectName}/events:report?key=123ABC456`` - - **Note:** [Error Reporting] - (https://cloud.google.com/error-reporting) is a service built on - Cloud Logging and can analyze log entries when all of the - following are true: - - - Customer-managed encryption keys (CMEK) are disabled on the - log bucket. - - The log bucket satisfies one of the following: - - - The log bucket is stored in the same project where the logs - originated. - - The logs were routed to a project, and then that project - stored those logs in a log bucket that it owns. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import errorreporting_v1beta1 - - async def sample_report_error_event(): - # Create a client - client = errorreporting_v1beta1.ReportErrorsServiceAsyncClient() - - # Initialize request argument(s) - event = errorreporting_v1beta1.ReportedErrorEvent() - event.message = "message_value" - - request = errorreporting_v1beta1.ReportErrorEventRequest( - project_name="project_name_value", - event=event, - ) - - # Make the request - response = await client.report_error_event(request=request) - - # Handle the response - print(response) - - Args: - request (Optional[Union[google.cloud.errorreporting_v1beta1.types.ReportErrorEventRequest, dict]]): - 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/{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. - 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. - retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud.errorreporting_v1beta1.types.ReportErrorEventResponse: - Response for reporting an individual - error event. Data may be added to this - message in the future. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [project_name, event] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, report_errors_service.ReportErrorEventRequest): - request = report_errors_service.ReportErrorEventRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if project_name is not None: - request.project_name = project_name - if event is not None: - request.event = event - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.report_error_event - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("project_name", request.project_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ReportErrorsServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ReportErrorsServiceAsyncClient",) diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py deleted file mode 100644 index 24414830..00000000 --- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/client.py +++ /dev/null @@ -1,885 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - Mapping, - MutableMapping, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.cloud.errorreporting_v1beta1 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - -from google.cloud.errorreporting_v1beta1.types import report_errors_service -from .transports.base import ReportErrorsServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import ReportErrorsServiceGrpcTransport -from .transports.grpc_asyncio import ReportErrorsServiceGrpcAsyncIOTransport -from .transports.rest import ReportErrorsServiceRestTransport - - -class ReportErrorsServiceClientMeta(type): - """Metaclass for the ReportErrorsService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ReportErrorsServiceTransport]] - _transport_registry["grpc"] = ReportErrorsServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ReportErrorsServiceGrpcAsyncIOTransport - _transport_registry["rest"] = ReportErrorsServiceRestTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ReportErrorsServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ReportErrorsServiceClient(metaclass=ReportErrorsServiceClientMeta): - """An API for reporting error events.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "clouderrorreporting.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "clouderrorreporting.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @staticmethod - def _use_client_cert_effective(): - """Returns whether client certificate should be used for mTLS if the - google-auth version supports should_use_client_cert automatic mTLS enablement. - - Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. - - Returns: - bool: whether client certificate should be used for mTLS - Raises: - ValueError: (If using a version of google-auth without should_use_client_cert and - GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) - """ - # check if google-auth version supports should_use_client_cert for automatic mTLS enablement - if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER - return mtls.should_use_client_cert() - else: # pragma: NO COVER - # if unsupported, fallback to reading from env var - use_client_cert_str = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - if use_client_cert_str not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" - " either `true` or `false`" - ) - return use_client_cert_str == "true" - - @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 - 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: - ReportErrorsServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file(filename) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ReportErrorsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ReportErrorsServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = ReportErrorsServiceClient._use_client_cert_effective() - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert: - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = ReportErrorsServiceClient._use_client_cert_effective() - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert, use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ReportErrorsServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ReportErrorsServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ReportErrorsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], universe_domain_env: Optional[str] - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ReportErrorsServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ReportErrorsServiceTransport, - Callable[..., ReportErrorsServiceTransport], - ] - ] = None, - client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the report errors service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ReportErrorsServiceTransport,Callable[..., ReportErrorsServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ReportErrorsServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict(self._client_options) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr(self._client_options, "universe_domain", None) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ReportErrorsServiceClient._read_environment_variables() - self._client_cert_source = ReportErrorsServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - self._universe_domain = ReportErrorsServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # Initialize the universe domain validation. - self._is_universe_domain_valid = False - - if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER - # Setup logging. - client_logging.initialize_logging() - - api_key_value = getattr(self._client_options, "api_key", None) - if api_key_value and credentials: - raise ValueError( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, ReportErrorsServiceTransport) - if transport_provided: - # transport is a ReportErrorsServiceTransport instance. - if credentials or self._client_options.credentials_file or api_key_value: - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(ReportErrorsServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ReportErrorsServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ReportErrorsServiceTransport], - Callable[..., ReportErrorsServiceTransport], - ] = ( - ReportErrorsServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., ReportErrorsServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - api_audience=self._client_options.api_audience, - ) - - if "async" not in str(self._transport): - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.devtools.clouderrorreporting_v1beta1.ReportErrorsServiceClient`.", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - "universeDomain": getattr( - self._transport._credentials, "universe_domain", "" - ), - "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}", - "credentialsInfo": getattr( - self.transport._credentials, "get_cred_info", lambda: None - )(), - } - if hasattr(self._transport, "_credentials") - else { - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - "credentialsType": None, - }, - ) - - def report_error_event( - self, - request: Optional[ - Union[report_errors_service.ReportErrorEventRequest, dict] - ] = None, - *, - project_name: Optional[str] = None, - event: Optional[report_errors_service.ReportedErrorEvent] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> report_errors_service.ReportErrorEventResponse: - 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/{projectName}/events:report?key=123ABC456`` - - **Note:** [Error Reporting] - (https://cloud.google.com/error-reporting) is a service built on - Cloud Logging and can analyze log entries when all of the - following are true: - - - Customer-managed encryption keys (CMEK) are disabled on the - log bucket. - - The log bucket satisfies one of the following: - - - The log bucket is stored in the same project where the logs - originated. - - The logs were routed to a project, and then that project - stored those logs in a log bucket that it owns. - - .. code-block:: python - - # This snippet has been automatically generated and should be regarded as a - # code template only. - # It will require modifications to work: - # - It may require correct/in-range values for request initialization. - # - It may require specifying regional endpoints when creating the service - # client as shown in: - # https://googleapis.dev/python/google-api-core/latest/client_options.html - from google.cloud import errorreporting_v1beta1 - - def sample_report_error_event(): - # Create a client - client = errorreporting_v1beta1.ReportErrorsServiceClient() - - # Initialize request argument(s) - event = errorreporting_v1beta1.ReportedErrorEvent() - event.message = "message_value" - - request = errorreporting_v1beta1.ReportErrorEventRequest( - project_name="project_name_value", - event=event, - ) - - # Make the request - response = client.report_error_event(request=request) - - # Handle the response - print(response) - - Args: - request (Union[google.cloud.errorreporting_v1beta1.types.ReportErrorEventRequest, dict]): - The request object. A request for reporting an individual - error event. - project_name (str): - Required. The resource name of the Google Cloud Platform - 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. - 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. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - google.cloud.errorreporting_v1beta1.types.ReportErrorEventResponse: - Response for reporting an individual - error event. Data may be added to this - message in the future. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [project_name, event] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, report_errors_service.ReportErrorEventRequest): - request = report_errors_service.ReportErrorEventRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if project_name is not None: - request.project_name = project_name - if event is not None: - request.event = event - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.report_error_event] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("project_name", request.project_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ReportErrorsServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ReportErrorsServiceClient",) diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/README.rst b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/README.rst deleted file mode 100644 index d70e9010..00000000 --- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/README.rst +++ /dev/null @@ -1,9 +0,0 @@ - -transport inheritance structure -_______________________________ - -`ReportErrorsServiceTransport` is the ABC for all transports. -- public child `ReportErrorsServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). -- public child `ReportErrorsServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). -- private child `_BaseReportErrorsServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). -- public child `ReportErrorsServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/__init__.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/__init__.py deleted file mode 100644 index 83aa46c6..00000000 --- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/__init__.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from typing import Dict, Type - -from .base import ReportErrorsServiceTransport -from .grpc import ReportErrorsServiceGrpcTransport -from .grpc_asyncio import ReportErrorsServiceGrpcAsyncIOTransport -from .rest import ReportErrorsServiceRestTransport -from .rest import ReportErrorsServiceRestInterceptor - - -# Compile a registry of transports. -_transport_registry = ( - OrderedDict() -) # type: Dict[str, Type[ReportErrorsServiceTransport]] -_transport_registry["grpc"] = ReportErrorsServiceGrpcTransport -_transport_registry["grpc_asyncio"] = ReportErrorsServiceGrpcAsyncIOTransport -_transport_registry["rest"] = ReportErrorsServiceRestTransport - -__all__ = ( - "ReportErrorsServiceTransport", - "ReportErrorsServiceGrpcTransport", - "ReportErrorsServiceGrpcAsyncIOTransport", - "ReportErrorsServiceRestTransport", - "ReportErrorsServiceRestInterceptor", -) 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 deleted file mode 100644 index 4a121c36..00000000 --- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/base.py +++ /dev/null @@ -1,173 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Dict, Optional, Sequence, Union - -from google.cloud.errorreporting_v1beta1 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.cloud.errorreporting_v1beta1.types import report_errors_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ReportErrorsServiceTransport(abc.ABC): - """Abstract transport class for ReportErrorsService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) - - DEFAULT_HOST: str = "clouderrorreporting.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. This argument will be - removed in the next major version of this library. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - default_scopes=self.AUTH_SCOPES, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - scopes=scopes, - quota_project_id=quota_project_id, - default_scopes=self.AUTH_SCOPES, - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr(service_account.Credentials, "with_always_use_jwt_access") - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.report_error_event: gapic_v1.method.wrap_method( - self.report_error_event, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def report_error_event( - self, - ) -> Callable[ - [report_errors_service.ReportErrorEventRequest], - Union[ - report_errors_service.ReportErrorEventResponse, - Awaitable[report_errors_service.ReportErrorEventResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ReportErrorsServiceTransport",) 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 deleted file mode 100644 index 2fe1f2d5..00000000 --- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc.py +++ /dev/null @@ -1,383 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import json -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -import google.auth # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore - -from google.cloud.errorreporting_v1beta1.types import report_errors_service -from .base import ReportErrorsServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" - - request_metadata = { - key: value.decode("utf-8") if isinstance(value, bytes) else value - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - "rpcName": str(client_call_details.method), - "request": grpc_request, - "metadata": grpc_request["metadata"], - }, - ) - response = continuation(client_call_details, request) - if logging_enabled: # pragma: NO COVER - response_metadata = response.trailing_metadata() - # Convert gRPC metadata `` to list of tuples - metadata = ( - dict([(k, str(v)) for k, v in response_metadata]) - if response_metadata - else None - ) - result = response.result() - if isinstance(result, proto.Message): - response_payload = type(result).to_json(result) - elif isinstance(result, google.protobuf.message.Message): - response_payload = MessageToJson(result) - else: - response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" - grpc_response = { - "payload": response_payload, - "metadata": metadata, - "status": "OK", - } - _LOGGER.debug( - f"Received response for {client_call_details.method}.", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ReportErrorsServiceGrpcTransport(ReportErrorsServiceTransport): - """gRPC backend transport for ReportErrorsService. - - An API for reporting error events. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - This argument will be removed in the next major version of this library. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - self._interceptor = _LoggingClientInterceptor() - self._logged_channel = grpc.intercept_channel( - self._grpc_channel, self._interceptor - ) - - # Wrap messages. This must be done after self._logged_channel exists - self._prep_wrapped_messages(client_info) - - @classmethod - def create_channel( - cls, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. This argument will be - removed in the next major version of this library. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def report_error_event( - self, - ) -> Callable[ - [report_errors_service.ReportErrorEventRequest], - report_errors_service.ReportErrorEventResponse, - ]: - r"""Return a callable for the report error event method over gRPC. - - 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/{projectName}/events:report?key=123ABC456`` - - **Note:** [Error Reporting] - (https://cloud.google.com/error-reporting) is a service built on - Cloud Logging and can analyze log entries when all of the - following are true: - - - Customer-managed encryption keys (CMEK) are disabled on the - log bucket. - - The log bucket satisfies one of the following: - - - The log bucket is stored in the same project where the logs - originated. - - The logs were routed to a project, and then that project - stored those logs in a log bucket that it owns. - - Returns: - Callable[[~.ReportErrorEventRequest], - ~.ReportErrorEventResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "report_error_event" not in self._stubs: - self._stubs["report_error_event"] = self._logged_channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ReportErrorsService/ReportErrorEvent", - request_serializer=report_errors_service.ReportErrorEventRequest.serialize, - response_deserializer=report_errors_service.ReportErrorEventResponse.deserialize, - ) - return self._stubs["report_error_event"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ReportErrorsServiceGrpcTransport",) 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 deleted file mode 100644 index 4f538187..00000000 --- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,406 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import json -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.api_core import exceptions as core_exceptions -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.cloud.errorreporting_v1beta1.types import report_errors_service -from .base import ReportErrorsServiceTransport, DEFAULT_CLIENT_INFO -from .grpc import ReportErrorsServiceGrpcTransport - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientAIOInterceptor( - grpc.aio.UnaryUnaryClientInterceptor -): # pragma: NO COVER - async def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" - - request_metadata = { - key: value.decode("utf-8") if isinstance(value, bytes) else value - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - "rpcName": str(client_call_details.method), - "request": grpc_request, - "metadata": grpc_request["metadata"], - }, - ) - response = await continuation(client_call_details, request) - if logging_enabled: # pragma: NO COVER - response_metadata = await response.trailing_metadata() - # Convert gRPC metadata `` to list of tuples - metadata = ( - dict([(k, str(v)) for k, v in response_metadata]) - if response_metadata - else None - ) - result = await response - if isinstance(result, proto.Message): - response_payload = type(result).to_json(result) - elif isinstance(result, google.protobuf.message.Message): - response_payload = MessageToJson(result) - else: - response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" - grpc_response = { - "payload": response_payload, - "metadata": metadata, - "status": "OK", - } - _LOGGER.debug( - f"Received response to rpc {client_call_details.method}.", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ReportErrorsServiceGrpcAsyncIOTransport(ReportErrorsServiceTransport): - """gRPC AsyncIO backend transport for ReportErrorsService. - - An API for reporting error events. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be - removed in the next major version of this library. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - This argument will be removed in the next major version of this library. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn("client_cert_source is deprecated", DeprecationWarning) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - else: - self._ssl_channel_credentials = SslCredentials().ssl_credentials - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - self._interceptor = _LoggingClientAIOInterceptor() - self._grpc_channel._unary_unary_interceptors.append(self._interceptor) - self._logged_channel = self._grpc_channel - self._wrap_with_kind = ( - "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters - ) - # Wrap messages. This must be done after self._logged_channel exists - self._prep_wrapped_messages(client_info) - - @property - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def report_error_event( - self, - ) -> Callable[ - [report_errors_service.ReportErrorEventRequest], - Awaitable[report_errors_service.ReportErrorEventResponse], - ]: - r"""Return a callable for the report error event method over gRPC. - - 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/{projectName}/events:report?key=123ABC456`` - - **Note:** [Error Reporting] - (https://cloud.google.com/error-reporting) is a service built on - Cloud Logging and can analyze log entries when all of the - following are true: - - - Customer-managed encryption keys (CMEK) are disabled on the - log bucket. - - The log bucket satisfies one of the following: - - - The log bucket is stored in the same project where the logs - originated. - - The logs were routed to a project, and then that project - stored those logs in a log bucket that it owns. - - Returns: - Callable[[~.ReportErrorEventRequest], - Awaitable[~.ReportErrorEventResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "report_error_event" not in self._stubs: - self._stubs["report_error_event"] = self._logged_channel.unary_unary( - "/google.devtools.clouderrorreporting.v1beta1.ReportErrorsService/ReportErrorEvent", - request_serializer=report_errors_service.ReportErrorEventRequest.serialize, - response_deserializer=report_errors_service.ReportErrorEventResponse.deserialize, - ) - return self._stubs["report_error_event"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.report_error_event: self._wrap_method( - self.report_error_event, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ReportErrorsServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/rest.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/rest.py deleted file mode 100644 index 9cebe03c..00000000 --- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/rest.py +++ /dev/null @@ -1,413 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -import json # type: ignore - -from google.auth.transport.requests import AuthorizedSession # type: ignore -from google.auth import credentials as ga_credentials # type: ignore -from google.api_core import exceptions as core_exceptions -from google.api_core import retry as retries -from google.api_core import rest_helpers -from google.api_core import rest_streaming -from google.api_core import gapic_v1 -import google.protobuf - -from google.protobuf import json_format - -from requests import __version__ as requests_version -import dataclasses -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union -import warnings - - -from google.cloud.errorreporting_v1beta1.types import report_errors_service - - -from .rest_base import _BaseReportErrorsServiceRestTransport -from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = logging.getLogger(__name__) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, - grpc_version=None, - rest_version=f"requests@{requests_version}", -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ReportErrorsServiceRestInterceptor: - """Interceptor for ReportErrorsService. - - Interceptors are used to manipulate requests, request metadata, and responses - in arbitrary ways. - Example use cases include: - * Logging - * Verifying requests according to service or custom semantics - * Stripping extraneous information from responses - - These use cases and more can be enabled by injecting an - instance of a custom subclass when constructing the ReportErrorsServiceRestTransport. - - .. code-block:: python - class MyCustomReportErrorsServiceInterceptor(ReportErrorsServiceRestInterceptor): - def pre_report_error_event(self, request, metadata): - logging.log(f"Received request: {request}") - return request, metadata - - def post_report_error_event(self, response): - logging.log(f"Received response: {response}") - return response - - transport = ReportErrorsServiceRestTransport(interceptor=MyCustomReportErrorsServiceInterceptor()) - client = ReportErrorsServiceClient(transport=transport) - - - """ - - def pre_report_error_event( - self, - request: report_errors_service.ReportErrorEventRequest, - metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - report_errors_service.ReportErrorEventRequest, - Sequence[Tuple[str, Union[str, bytes]]], - ]: - """Pre-rpc interceptor for report_error_event - - Override in a subclass to manipulate the request or metadata - before they are sent to the ReportErrorsService server. - """ - return request, metadata - - def post_report_error_event( - self, response: report_errors_service.ReportErrorEventResponse - ) -> report_errors_service.ReportErrorEventResponse: - """Post-rpc interceptor for report_error_event - - DEPRECATED. Please use the `post_report_error_event_with_metadata` - interceptor instead. - - Override in a subclass to read or manipulate the response - after it is returned by the ReportErrorsService server but before - it is returned to user code. This `post_report_error_event` interceptor runs - before the `post_report_error_event_with_metadata` interceptor. - """ - return response - - def post_report_error_event_with_metadata( - self, - response: report_errors_service.ReportErrorEventResponse, - metadata: Sequence[Tuple[str, Union[str, bytes]]], - ) -> Tuple[ - report_errors_service.ReportErrorEventResponse, - Sequence[Tuple[str, Union[str, bytes]]], - ]: - """Post-rpc interceptor for report_error_event - - Override in a subclass to read or manipulate the response or metadata after it - is returned by the ReportErrorsService server but before it is returned to user code. - - We recommend only using this `post_report_error_event_with_metadata` - interceptor in new development instead of the `post_report_error_event` interceptor. - When both interceptors are used, this `post_report_error_event_with_metadata` interceptor runs after the - `post_report_error_event` interceptor. The (possibly modified) response returned by - `post_report_error_event` will be passed to - `post_report_error_event_with_metadata`. - """ - return response, metadata - - -@dataclasses.dataclass -class ReportErrorsServiceRestStub: - _session: AuthorizedSession - _host: str - _interceptor: ReportErrorsServiceRestInterceptor - - -class ReportErrorsServiceRestTransport(_BaseReportErrorsServiceRestTransport): - """REST backend synchronous transport for ReportErrorsService. - - An API for reporting error events. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends JSON representations of protocol buffers over HTTP/1.1 - """ - - def __init__( - self, - *, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - url_scheme: str = "https", - interceptor: Optional[ReportErrorsServiceRestInterceptor] = None, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - - credentials_file (Optional[str]): Deprecated. A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if ``channel`` is provided. This argument will be - removed in the next major version of this library. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if ``channel`` is provided. - client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client - certificate to configure mutual TLS HTTP channel. It is ignored - if ``channel`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you are developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - url_scheme: the protocol scheme for the API endpoint. Normally - "https", but for testing or local servers, - "http" can be specified. - """ - # Run the base constructor - # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. - # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the - # credentials object - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - url_scheme=url_scheme, - api_audience=api_audience, - ) - self._session = AuthorizedSession( - self._credentials, default_host=self.DEFAULT_HOST - ) - if client_cert_source_for_mtls: - self._session.configure_mtls_channel(client_cert_source_for_mtls) - self._interceptor = interceptor or ReportErrorsServiceRestInterceptor() - self._prep_wrapped_messages(client_info) - - class _ReportErrorEvent( - _BaseReportErrorsServiceRestTransport._BaseReportErrorEvent, - ReportErrorsServiceRestStub, - ): - def __hash__(self): - return hash("ReportErrorsServiceRestTransport.ReportErrorEvent") - - @staticmethod - def _get_response( - host, - metadata, - query_params, - session, - timeout, - transcoded_request, - body=None, - ): - uri = transcoded_request["uri"] - method = transcoded_request["method"] - headers = dict(metadata) - headers["Content-Type"] = "application/json" - response = getattr(session, method)( - "{host}{uri}".format(host=host, uri=uri), - timeout=timeout, - headers=headers, - params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, - ) - return response - - def __call__( - self, - request: report_errors_service.ReportErrorEventRequest, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Optional[float] = None, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> report_errors_service.ReportErrorEventResponse: - r"""Call the report error event method over HTTP. - - Args: - request (~.report_errors_service.ReportErrorEventRequest): - The request object. A request for reporting an individual - error event. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each value must be of type `str`, - but for metadata keys ending with the suffix `-bin`, the corresponding values must - be of type `bytes`. - - Returns: - ~.report_errors_service.ReportErrorEventResponse: - Response for reporting an individual - error event. Data may be added to this - message in the future. - - """ - - http_options = ( - _BaseReportErrorsServiceRestTransport._BaseReportErrorEvent._get_http_options() - ) - - request, metadata = self._interceptor.pre_report_error_event( - request, metadata - ) - transcoded_request = _BaseReportErrorsServiceRestTransport._BaseReportErrorEvent._get_transcoded_request( - http_options, request - ) - - body = _BaseReportErrorsServiceRestTransport._BaseReportErrorEvent._get_request_body_json( - transcoded_request - ) - - # Jsonify the query params - query_params = _BaseReportErrorsServiceRestTransport._BaseReportErrorEvent._get_query_params_json( - transcoded_request - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - logging.DEBUG - ): # pragma: NO COVER - request_url = "{host}{uri}".format( - host=self._host, uri=transcoded_request["uri"] - ) - method = transcoded_request["method"] - try: - request_payload = type(request).to_json(request) - except: - request_payload = None - http_request = { - "payload": request_payload, - "requestMethod": method, - "requestUrl": request_url, - "headers": dict(metadata), - } - _LOGGER.debug( - f"Sending request for google.devtools.clouderrorreporting_v1beta1.ReportErrorsServiceClient.ReportErrorEvent", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - "rpcName": "ReportErrorEvent", - "httpRequest": http_request, - "metadata": http_request["headers"], - }, - ) - - # Send the request - response = ReportErrorsServiceRestTransport._ReportErrorEvent._get_response( - self._host, - metadata, - query_params, - self._session, - timeout, - transcoded_request, - body, - ) - - # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception - # subclass. - if response.status_code >= 400: - raise core_exceptions.from_http_response(response) - - # Return the response - resp = report_errors_service.ReportErrorEventResponse() - pb_resp = report_errors_service.ReportErrorEventResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - - resp = self._interceptor.post_report_error_event(resp) - response_metadata = [(k, str(v)) for k, v in response.headers.items()] - resp, _ = self._interceptor.post_report_error_event_with_metadata( - resp, response_metadata - ) - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - logging.DEBUG - ): # pragma: NO COVER - try: - response_payload = ( - report_errors_service.ReportErrorEventResponse.to_json(response) - ) - except: - response_payload = None - http_response = { - "payload": response_payload, - "headers": dict(response.headers), - "status": response.status_code, - } - _LOGGER.debug( - "Received response for google.devtools.clouderrorreporting_v1beta1.ReportErrorsServiceClient.report_error_event", - extra={ - "serviceName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - "rpcName": "ReportErrorEvent", - "metadata": http_response["headers"], - "httpResponse": http_response, - }, - ) - return resp - - @property - def report_error_event( - self, - ) -> Callable[ - [report_errors_service.ReportErrorEventRequest], - report_errors_service.ReportErrorEventResponse, - ]: - # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. - # In C++ this would require a dynamic_cast - return self._ReportErrorEvent(self._session, self._host, self._interceptor) # type: ignore - - @property - def kind(self) -> str: - return "rest" - - def close(self): - self._session.close() - - -__all__ = ("ReportErrorsServiceRestTransport",) diff --git a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/rest_base.py b/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/rest_base.py deleted file mode 100644 index f6495841..00000000 --- a/google/cloud/errorreporting_v1beta1/services/report_errors_service/transports/rest_base.py +++ /dev/null @@ -1,150 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import json # type: ignore -from google.api_core import path_template -from google.api_core import gapic_v1 - -from google.protobuf import json_format -from .base import ReportErrorsServiceTransport, DEFAULT_CLIENT_INFO - -import re -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union - - -from google.cloud.errorreporting_v1beta1.types import report_errors_service - - -class _BaseReportErrorsServiceRestTransport(ReportErrorsServiceTransport): - """Base REST backend transport for ReportErrorsService. - - Note: This class is not meant to be used directly. Use its sync and - async sub-classes instead. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends JSON representations of protocol buffers over HTTP/1.1 - """ - - def __init__( - self, - *, - host: str = "clouderrorreporting.googleapis.com", - credentials: Optional[Any] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - url_scheme: str = "https", - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - Args: - host (Optional[str]): - The hostname to connect to (default: 'clouderrorreporting.googleapis.com'). - credentials (Optional[Any]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you are developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - url_scheme: the protocol scheme for the API endpoint. Normally - "https", but for testing or local servers, - "http" can be specified. - """ - # Run the base constructor - maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) - if maybe_url_match is None: - raise ValueError( - f"Unexpected hostname structure: {host}" - ) # pragma: NO COVER - - url_match_items = maybe_url_match.groupdict() - - host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host - - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - class _BaseReportErrorEvent: - def __hash__(self): # pragma: NO COVER - return NotImplementedError("__hash__ must be implemented.") - - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} - - @classmethod - def _get_unset_required_fields(cls, message_dict): - return { - k: v - for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() - if k not in message_dict - } - - @staticmethod - def _get_http_options(): - http_options: List[Dict[str, str]] = [ - { - "method": "post", - "uri": "/v1beta1/{project_name=projects/*}/events:report", - "body": "event", - }, - ] - return http_options - - @staticmethod - def _get_transcoded_request(http_options, request): - pb_request = report_errors_service.ReportErrorEventRequest.pb(request) - transcoded_request = path_template.transcode(http_options, pb_request) - return transcoded_request - - @staticmethod - def _get_request_body_json(transcoded_request): - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True - ) - return body - - @staticmethod - def _get_query_params_json(transcoded_request): - query_params = json.loads( - json_format.MessageToJson( - transcoded_request["query_params"], - use_integers_for_enums=True, - ) - ) - query_params.update( - _BaseReportErrorsServiceRestTransport._BaseReportErrorEvent._get_unset_required_fields( - query_params - ) - ) - - query_params["$alt"] = "json;enum-encoding=int" - return query_params - - -__all__ = ("_BaseReportErrorsServiceRestTransport",) diff --git a/google/cloud/errorreporting_v1beta1/types/__init__.py b/google/cloud/errorreporting_v1beta1/types/__init__.py deleted file mode 100644 index 4acdb9a1..00000000 --- a/google/cloud/errorreporting_v1beta1/types/__init__.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .common import ( - ErrorContext, - ErrorEvent, - ErrorGroup, - HttpRequestContext, - ServiceContext, - SourceLocation, - TrackingIssue, - ResolutionStatus, -) -from .error_group_service import ( - GetGroupRequest, - UpdateGroupRequest, -) -from .error_stats_service import ( - DeleteEventsRequest, - DeleteEventsResponse, - ErrorGroupStats, - ListEventsRequest, - ListEventsResponse, - ListGroupStatsRequest, - ListGroupStatsResponse, - QueryTimeRange, - ServiceContextFilter, - TimedCount, - ErrorGroupOrder, - TimedCountAlignment, -) -from .report_errors_service import ( - ReportedErrorEvent, - ReportErrorEventRequest, - ReportErrorEventResponse, -) - -__all__ = ( - "ErrorContext", - "ErrorEvent", - "ErrorGroup", - "HttpRequestContext", - "ServiceContext", - "SourceLocation", - "TrackingIssue", - "ResolutionStatus", - "GetGroupRequest", - "UpdateGroupRequest", - "DeleteEventsRequest", - "DeleteEventsResponse", - "ErrorGroupStats", - "ListEventsRequest", - "ListEventsResponse", - "ListGroupStatsRequest", - "ListGroupStatsResponse", - "QueryTimeRange", - "ServiceContextFilter", - "TimedCount", - "ErrorGroupOrder", - "TimedCountAlignment", - "ReportedErrorEvent", - "ReportErrorEventRequest", - "ReportErrorEventResponse", -) diff --git a/google/cloud/errorreporting_v1beta1/types/common.py b/google/cloud/errorreporting_v1beta1/types/common.py deleted file mode 100644 index d50ed7f7..00000000 --- a/google/cloud/errorreporting_v1beta1/types/common.py +++ /dev/null @@ -1,366 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -from typing import MutableMapping, MutableSequence - -import proto # type: ignore - -import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore - - -__protobuf__ = proto.module( - package="google.devtools.clouderrorreporting.v1beta1", - manifest={ - "ResolutionStatus", - "ErrorGroup", - "TrackingIssue", - "ErrorEvent", - "ServiceContext", - "ErrorContext", - "HttpRequestContext", - "SourceLocation", - }, -) - - -class ResolutionStatus(proto.Enum): - r"""Resolution status of an error group. - - Values: - RESOLUTION_STATUS_UNSPECIFIED (0): - Status is unknown. When left unspecified in - requests, it is treated like OPEN. - OPEN (1): - 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. - ACKNOWLEDGED (2): - Error Group manually acknowledged, it can - have an issue link attached. - RESOLVED (3): - Error Group manually resolved, more events - for this group are not expected to occur. - MUTED (4): - The error group is muted and excluded by - default on group stats requests. - """ - 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. - - Attributes: - name (str): - The group resource name. Written as - ``projects/{projectID}/groups/{group_id}`` or - ``projects/{projectID}/locations/{location}/groups/{group_id}`` - - Examples: ``projects/my-project-123/groups/my-group``, - ``projects/my-project-123/locations/us-central1/groups/my-group`` - - In the group resource name, the ``group_id`` is a unique - identifier for a particular error group. The identifier is - derived from key parts of the error-log content and is - treated as Service Data. For information about how Service - Data is handled, see `Google Cloud Privacy - Notice `__. - - For a list of supported locations, see `Supported - Regions `__. - ``global`` is the default when unspecified. - group_id (str): - An opaque identifier of the group. This field is assigned by - the Error Reporting system and always populated. - - In the group resource name, the ``group_id`` is a unique - identifier for a particular error group. The identifier is - derived from key parts of the error-log content and is - treated as Service Data. For information about how Service - Data is handled, see `Google Cloud Privacy - Notice `__. - tracking_issues (MutableSequence[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: str = proto.Field( - proto.STRING, - number=1, - ) - group_id: str = proto.Field( - proto.STRING, - number=2, - ) - tracking_issues: MutableSequence["TrackingIssue"] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message="TrackingIssue", - ) - resolution_status: "ResolutionStatus" = proto.Field( - proto.ENUM, - number=5, - enum="ResolutionStatus", - ) - - -class TrackingIssue(proto.Message): - r"""Information related to tracking the progress on resolving the - error. - - Attributes: - url (str): - A URL pointing to a related entry in an issue tracking - system. Example: - ``https://github.com/user/project/issues/4`` - """ - - url: str = proto.Field( - proto.STRING, - number=1, - ) - - -class ErrorEvent(proto.Message): - r"""An error event which is returned by the Error Reporting - system. - - Attributes: - 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 (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 (google.cloud.errorreporting_v1beta1.types.ErrorContext): - Data about the context in which the error - occurred. - """ - - event_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=1, - message=timestamp_pb2.Timestamp, - ) - service_context: "ServiceContext" = proto.Field( - proto.MESSAGE, - number=2, - message="ServiceContext", - ) - message: str = proto.Field( - proto.STRING, - number=3, - ) - context: "ErrorContext" = proto.Field( - proto.MESSAGE, - number=5, - message="ErrorContext", - ) - - -class ServiceContext(proto.Message): - r"""Describes a running service that sends errors. - Its version changes over time and multiple versions can run in - parallel. - - Attributes: - service (str): - An identifier of the service, such as the name of the - executable, job, or Google App Engine service name. This - field is expected to have a low number of values that are - relatively stable over time, as opposed to ``version``, - which can be changed whenever new code is deployed. - - Contains the service name for error reports extracted from - Google App Engine logs or ``default`` if the App Engine - default service is used. - version (str): - Represents the source code version that the - developer provided, which could represent a - version label or a Git SHA-1 hash, for example. - For App Engine standard environment, the version - is set to the version of the app. - resource_type (str): - Type of the MonitoredResource. List of - possible values: - https://cloud.google.com/monitoring/api/resources - - Value is set automatically for incoming errors - and must not be set when reporting errors. - """ - - service: str = proto.Field( - proto.STRING, - number=2, - ) - version: str = proto.Field( - proto.STRING, - number=3, - ) - resource_type: str = proto.Field( - proto.STRING, - number=4, - ) - - -class ErrorContext(proto.Message): - r"""A description of the context in which an error occurred. - This data should be provided by the application when reporting - an error, unless the - error report has been generated automatically from Google App - Engine logs. - - Attributes: - http_request (google.cloud.errorreporting_v1beta1.types.HttpRequestContext): - The HTTP request which was processed when the - error was triggered. - user (str): - The user who caused or was affected by the crash. This can - be a user ID, an email address, or an arbitrary token that - uniquely identifies the user. When sending an error report, - leave this field empty if the user was not logged in. In - 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 (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 - exception this would be the source line where - the exception is logged, usually close to the - place where it was caught. - """ - - http_request: "HttpRequestContext" = proto.Field( - proto.MESSAGE, - number=1, - message="HttpRequestContext", - ) - user: str = proto.Field( - proto.STRING, - number=2, - ) - report_location: "SourceLocation" = proto.Field( - proto.MESSAGE, - number=3, - message="SourceLocation", - ) - - -class HttpRequestContext(proto.Message): - r"""HTTP request data that is related to a reported error. - This data should be provided by the application when reporting - an error, unless the - error report has been generated automatically from Google App - Engine logs. - - Attributes: - method (str): - The type of HTTP request, such as ``GET``, ``POST``, etc. - url (str): - The URL of the request. - user_agent (str): - The user agent information that is provided - with the request. - referrer (str): - The referrer information that is provided - with the request. - response_status_code (int): - The HTTP response status code for the - request. - remote_ip (str): - The IP address from which the request - originated. This can be IPv4, IPv6, or a token - which is derived from the IP address, depending - on the data that has been provided in the error - report. - """ - - method: str = proto.Field( - proto.STRING, - number=1, - ) - url: str = proto.Field( - proto.STRING, - number=2, - ) - user_agent: str = proto.Field( - proto.STRING, - number=3, - ) - referrer: str = proto.Field( - proto.STRING, - number=4, - ) - response_status_code: int = proto.Field( - proto.INT32, - number=5, - ) - remote_ip: str = proto.Field( - proto.STRING, - number=6, - ) - - -class SourceLocation(proto.Message): - r"""Indicates a location in the source code of the service for which - errors are reported. ``functionName`` must be provided by the - application when reporting an error, unless the error report - contains a ``message`` with a supported exception stack trace. All - fields are optional for the later case. - - Attributes: - file_path (str): - The source code filename, which can include a - truncated relative path, or a full path from a - production machine. - line_number (int): - 1-based. 0 indicates that the line number is - unknown. - function_name (str): - Human-readable name of a function or method. The value can - include optional context like the class or package name. For - example, ``my.package.MyClass.method`` in case of Java. - """ - - file_path: str = proto.Field( - proto.STRING, - number=1, - ) - line_number: int = proto.Field( - proto.INT32, - number=2, - ) - function_name: str = proto.Field( - proto.STRING, - number=4, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/errorreporting_v1beta1/types/error_group_service.py b/google/cloud/errorreporting_v1beta1/types/error_group_service.py deleted file mode 100644 index be126768..00000000 --- a/google/cloud/errorreporting_v1beta1/types/error_group_service.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -from typing import MutableMapping, MutableSequence - -import proto # type: ignore - -from google.cloud.errorreporting_v1beta1.types import common - - -__protobuf__ = proto.module( - package="google.devtools.clouderrorreporting.v1beta1", - manifest={ - "GetGroupRequest", - "UpdateGroupRequest", - }, -) - - -class GetGroupRequest(proto.Message): - r"""A request to return an individual group. - - Attributes: - group_name (str): - Required. The group resource name. Written as either - ``projects/{projectID}/groups/{group_id}`` or - ``projects/{projectID}/locations/{location}/groups/{group_id}``. - Call [groupStats.list] - [google.devtools.clouderrorreporting.v1beta1.ErrorStatsService.ListGroupStats] - to return a list of groups belonging to this project. - - Examples: ``projects/my-project-123/groups/my-group``, - ``projects/my-project-123/locations/global/groups/my-group`` - - In the group resource name, the ``group_id`` is a unique - identifier for a particular error group. The identifier is - derived from key parts of the error-log content and is - treated as Service Data. For information about how Service - Data is handled, see `Google Cloud Privacy - Notice `__. - - For a list of supported locations, see `Supported - Regions `__. - ``global`` is the default when unspecified. - """ - - group_name: str = proto.Field( - proto.STRING, - number=1, - ) - - -class UpdateGroupRequest(proto.Message): - r"""A request to replace the existing data for the given group. - - Attributes: - group (google.cloud.errorreporting_v1beta1.types.ErrorGroup): - Required. The group which replaces the - resource on the server. - """ - - group: common.ErrorGroup = proto.Field( - proto.MESSAGE, - number=1, - message=common.ErrorGroup, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/errorreporting_v1beta1/types/error_stats_service.py b/google/cloud/errorreporting_v1beta1/types/error_stats_service.py deleted file mode 100644 index 5418d33e..00000000 --- a/google/cloud/errorreporting_v1beta1/types/error_stats_service.py +++ /dev/null @@ -1,634 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -from typing import MutableMapping, MutableSequence - -import proto # type: ignore - -from google.cloud.errorreporting_v1beta1.types import common -import google.protobuf.duration_pb2 as duration_pb2 # type: ignore -import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore - - -__protobuf__ = proto.module( - package="google.devtools.clouderrorreporting.v1beta1", - manifest={ - "TimedCountAlignment", - "ErrorGroupOrder", - "ListGroupStatsRequest", - "ListGroupStatsResponse", - "ErrorGroupStats", - "TimedCount", - "ListEventsRequest", - "ListEventsResponse", - "QueryTimeRange", - "ServiceContextFilter", - "DeleteEventsRequest", - "DeleteEventsResponse", - }, -) - - -class TimedCountAlignment(proto.Enum): - r"""Specifies how the time periods of error group counts are - aligned. - - Values: - ERROR_COUNT_ALIGNMENT_UNSPECIFIED (0): - No alignment specified. - ALIGNMENT_EQUAL_ROUNDED (1): - The time periods shall be consecutive, have width equal to - the requested duration, and be aligned at the - [alignment_time] - [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.alignment_time] - provided in the request. - - The [alignment_time] - [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.alignment_time] - does not have to be inside the query period but even if it - is outside, only time periods are returned which overlap - with the query period. - - A rounded alignment will typically result in a different - size of the first or the last time period. - ALIGNMENT_EQUAL_AT_END (2): - The time periods shall be consecutive, have - width equal to the requested duration, and be - aligned at the end of the requested time period. - This can result in a different size of the first - time period. - """ - ERROR_COUNT_ALIGNMENT_UNSPECIFIED = 0 - ALIGNMENT_EQUAL_ROUNDED = 1 - ALIGNMENT_EQUAL_AT_END = 2 - - -class ErrorGroupOrder(proto.Enum): - r"""A sorting order of error groups. - - Values: - GROUP_ORDER_UNSPECIFIED (0): - No group order specified. - COUNT_DESC (1): - Total count of errors in the given time - window in descending order. - LAST_SEEN_DESC (2): - Timestamp when the group was last seen in the - given time window in descending order. - CREATED_DESC (3): - Timestamp when the group was created in - descending order. - AFFECTED_USERS_DESC (4): - Number of affected users in the given time - window in descending order. - """ - GROUP_ORDER_UNSPECIFIED = 0 - COUNT_DESC = 1 - LAST_SEEN_DESC = 2 - CREATED_DESC = 3 - AFFECTED_USERS_DESC = 4 - - -class ListGroupStatsRequest(proto.Message): - r"""Specifies a set of ``ErrorGroupStats`` to return. - - Attributes: - 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 `__. - It may also include a location, such as - ``projects/{projectID}/locations/{location}`` where - ``{location}`` is a cloud region. - - Examples: ``projects/my-project-123``, ``projects/5551234``, - ``projects/my-project-123/locations/us-central1``, - ``projects/5551234/locations/us-central1``. - - For a list of supported locations, see `Supported - Regions `__. - ``global`` is the default when unspecified. Use ``-`` as a - wildcard to request group stats from all regions. - group_id (MutableSequence[str]): - Optional. List all [ErrorGroupStats] - [google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats] - with these IDs. The ``group_id`` is a unique identifier for - a particular error group. The identifier is derived from key - parts of the error-log content and is treated as Service - Data. For information about how Service Data is handled, see - [Google Cloud Privacy Notice] - (https://cloud.google.com/terms/cloud-privacy-notice). - service_filter (google.cloud.errorreporting_v1beta1.types.ServiceContextFilter): - Optional. List only [ErrorGroupStats] - [google.devtools.clouderrorreporting.v1beta1.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 (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] - [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsResponse.time_range_begin] - in the response will specify the beginning of this time - range. Only [ErrorGroupStats] - [google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats] - with a non-zero count in the given time range are returned, - unless the request contains an explicit [group_id] - [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.group_id] - list. If a [group_id] - [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsRequest.group_id] - list is given, also [ErrorGroupStats] - [google.devtools.clouderrorreporting.v1beta1.ErrorGroupStats] - with zero occurrences are returned. - timed_count_duration (google.protobuf.duration_pb2.Duration): - Optional. The preferred duration for a single returned - [TimedCount] - [google.devtools.clouderrorreporting.v1beta1.TimedCount]. If - not set, no timed counts are returned. - 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 (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 (google.cloud.errorreporting_v1beta1.types.ErrorGroupOrder): - Optional. The sort order in which the results are returned. - Default is ``COUNT_DESC``. - page_size (int): - Optional. The maximum number of results to - return per response. Default is 20. - page_token (str): - Optional. A [next_page_token] - [google.devtools.clouderrorreporting.v1beta1.ListGroupStatsResponse.next_page_token] - provided by a previous response. To view additional results, - pass this token along with the identical query parameters as - the first request. - """ - - project_name: str = proto.Field( - proto.STRING, - number=1, - ) - group_id: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=2, - ) - service_filter: "ServiceContextFilter" = proto.Field( - proto.MESSAGE, - number=3, - message="ServiceContextFilter", - ) - time_range: "QueryTimeRange" = proto.Field( - proto.MESSAGE, - number=5, - message="QueryTimeRange", - ) - timed_count_duration: duration_pb2.Duration = proto.Field( - proto.MESSAGE, - number=6, - message=duration_pb2.Duration, - ) - alignment: "TimedCountAlignment" = proto.Field( - proto.ENUM, - number=7, - enum="TimedCountAlignment", - ) - alignment_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=8, - message=timestamp_pb2.Timestamp, - ) - order: "ErrorGroupOrder" = proto.Field( - proto.ENUM, - number=9, - enum="ErrorGroupOrder", - ) - page_size: int = proto.Field( - proto.INT32, - number=11, - ) - page_token: str = proto.Field( - proto.STRING, - number=12, - ) - - -class ListGroupStatsResponse(proto.Message): - r"""Contains a set of requested error group stats. - - Attributes: - error_group_stats (MutableSequence[google.cloud.errorreporting_v1beta1.types.ErrorGroupStats]): - The error group stats which match the given - request. - next_page_token (str): - If non-empty, more results are available. - Pass this token, along with the same query - parameters as the first request, to view the - next page of results. - 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 - be adjusted to a later time if a project has - exceeded the storage quota and older data has - been deleted. - """ - - @property - def raw_page(self): - return self - - error_group_stats: MutableSequence["ErrorGroupStats"] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message="ErrorGroupStats", - ) - next_page_token: str = proto.Field( - proto.STRING, - number=2, - ) - time_range_begin: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=4, - message=timestamp_pb2.Timestamp, - ) - - -class ErrorGroupStats(proto.Message): - r"""Data extracted for a specific group based on certain filter - criteria, such as a given time period and/or service filter. - - Attributes: - group (google.cloud.errorreporting_v1beta1.types.ErrorGroup): - Group data that is independent of the filter - criteria. - count (int): - Approximate total number of events in the - given group that match the filter criteria. - affected_users_count (int): - Approximate number of affected users in the given group that - match the filter criteria. Users are distinguished by data - in the [ErrorContext] - [google.devtools.clouderrorreporting.v1beta1.ErrorContext] - of the individual error events, such as their login name or - their remote IP address in case of HTTP requests. The number - of affected users can be zero even if the number of errors - is non-zero if no data was provided from which the affected - user could be deduced. Users are counted based on data in - the request context that was 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 (MutableSequence[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 (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 (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 (MutableSequence[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`` - for the total count. - num_affected_services (int): - The total number of services with a non-zero - error count for the given filter criteria. - 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 - quick preview for the whole group. Events in the - group are usually sufficiently similar to each - other such that showing an arbitrary - representative provides insight into the - characteristics of the group as a whole. - """ - - group: common.ErrorGroup = proto.Field( - proto.MESSAGE, - number=1, - message=common.ErrorGroup, - ) - count: int = proto.Field( - proto.INT64, - number=2, - ) - affected_users_count: int = proto.Field( - proto.INT64, - number=3, - ) - timed_counts: MutableSequence["TimedCount"] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message="TimedCount", - ) - first_seen_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=5, - message=timestamp_pb2.Timestamp, - ) - last_seen_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=6, - message=timestamp_pb2.Timestamp, - ) - affected_services: MutableSequence[common.ServiceContext] = proto.RepeatedField( - proto.MESSAGE, - number=7, - message=common.ServiceContext, - ) - num_affected_services: int = proto.Field( - proto.INT32, - number=8, - ) - representative: common.ErrorEvent = proto.Field( - proto.MESSAGE, - number=9, - message=common.ErrorEvent, - ) - - -class TimedCount(proto.Message): - r"""The number of errors in a given time period. - All numbers are approximate since the error events are sampled - before counting them. - - Attributes: - count (int): - Approximate number of occurrences in the - given time period. - start_time (google.protobuf.timestamp_pb2.Timestamp): - Start of the time period to which ``count`` refers - (included). - end_time (google.protobuf.timestamp_pb2.Timestamp): - End of the time period to which ``count`` refers (excluded). - """ - - count: int = proto.Field( - proto.INT64, - number=1, - ) - start_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=2, - message=timestamp_pb2.Timestamp, - ) - end_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=3, - message=timestamp_pb2.Timestamp, - ) - - -class ListEventsRequest(proto.Message): - r"""Specifies a set of error events to return. - - Attributes: - project_name (str): - Required. The resource name of the Google Cloud Platform - project. Written as ``projects/{projectID}`` or - ``projects/{projectID}/locations/{location}``, where - ``{projectID}`` is the `Google Cloud Platform project - ID `__ and - ``{location}`` is a Cloud region. - - Examples: ``projects/my-project-123``, - ``projects/my-project-123/locations/global``. - - For a list of supported locations, see `Supported - Regions `__. - ``global`` is the default when unspecified. - group_id (str): - Required. The group for which events shall be returned. The - ``group_id`` is a unique identifier for a particular error - group. The identifier is derived from key parts of the - error-log content and is treated as Service Data. For - information about how Service Data is handled, see `Google - Cloud Privacy - Notice `__. - 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 (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 - range. - page_size (int): - Optional. The maximum number of results to - return per response. - page_token (str): - Optional. A ``next_page_token`` provided by a previous - response. - """ - - project_name: str = proto.Field( - proto.STRING, - number=1, - ) - group_id: str = proto.Field( - proto.STRING, - number=2, - ) - service_filter: "ServiceContextFilter" = proto.Field( - proto.MESSAGE, - number=3, - message="ServiceContextFilter", - ) - time_range: "QueryTimeRange" = proto.Field( - proto.MESSAGE, - number=4, - message="QueryTimeRange", - ) - page_size: int = proto.Field( - proto.INT32, - number=6, - ) - page_token: str = proto.Field( - proto.STRING, - number=7, - ) - - -class ListEventsResponse(proto.Message): - r"""Contains a set of requested error events. - - Attributes: - error_events (MutableSequence[google.cloud.errorreporting_v1beta1.types.ErrorEvent]): - The error events which match the given - request. - next_page_token (str): - If non-empty, more results are available. - Pass this token, along with the same query - parameters as the first request, to view the - next page of results. - time_range_begin (google.protobuf.timestamp_pb2.Timestamp): - The timestamp specifies the start time to - which the request was restricted. - """ - - @property - def raw_page(self): - return self - - error_events: MutableSequence[common.ErrorEvent] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=common.ErrorEvent, - ) - next_page_token: str = proto.Field( - proto.STRING, - number=2, - ) - time_range_begin: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=4, - message=timestamp_pb2.Timestamp, - ) - - -class QueryTimeRange(proto.Message): - r"""A time range for which error group data shall be displayed. - Query time ranges end at 'now'. - When longer time ranges are selected, the resolution of the data - decreases. The description of each time range below indicates - the suggested minimum timed count duration for that range. - - Requests might be rejected or the resulting timed count - durations might be adjusted for lower durations. - - Attributes: - period (google.cloud.errorreporting_v1beta1.types.QueryTimeRange.Period): - Restricts the query to the specified time - range. - """ - - class Period(proto.Enum): - r"""The supported time ranges. - - Values: - PERIOD_UNSPECIFIED (0): - Do not use. - PERIOD_1_HOUR (1): - Retrieve data for the last hour. - Recommended minimum timed count duration: 1 min. - PERIOD_6_HOURS (2): - Retrieve data for the last 6 hours. - Recommended minimum timed count duration: 10 - min. - PERIOD_1_DAY (3): - Retrieve data for the last day. - Recommended minimum timed count duration: 1 - hour. - PERIOD_1_WEEK (4): - Retrieve data for the last week. - Recommended minimum timed count duration: 6 - hours. - PERIOD_30_DAYS (5): - Retrieve data for the last 30 days. - Recommended minimum timed count duration: 1 day. - """ - PERIOD_UNSPECIFIED = 0 - PERIOD_1_HOUR = 1 - PERIOD_6_HOURS = 2 - PERIOD_1_DAY = 3 - PERIOD_1_WEEK = 4 - PERIOD_30_DAYS = 5 - - period: Period = proto.Field( - proto.ENUM, - number=1, - enum=Period, - ) - - -class ServiceContextFilter(proto.Message): - r"""Specifies criteria for filtering a subset of service contexts. The - fields in the filter correspond to the fields in ``ServiceContext``. - Only exact, case-sensitive matches are supported. If a field is - unset or empty, it matches arbitrary values. - - Attributes: - service (str): - Optional. The exact value to match against - ```ServiceContext.service`` `__. - version (str): - Optional. The exact value to match against - ```ServiceContext.version`` `__. - resource_type (str): - Optional. The exact value to match against - ```ServiceContext.resource_type`` `__. - """ - - service: str = proto.Field( - proto.STRING, - number=2, - ) - version: str = proto.Field( - proto.STRING, - number=3, - ) - resource_type: str = proto.Field( - proto.STRING, - number=4, - ) - - -class DeleteEventsRequest(proto.Message): - r"""Deletes all events in the project. - - Attributes: - project_name (str): - Required. The resource name of the Google Cloud Platform - project. Written as ``projects/{projectID}`` or - ``projects/{projectID}/locations/{location}``, where - ``{projectID}`` is the `Google Cloud Platform project - ID `__ and - ``{location}`` is a Cloud region. - - Examples: ``projects/my-project-123``, - ``projects/my-project-123/locations/global``. - - For a list of supported locations, see `Supported - Regions `__. - ``global`` is the default when unspecified. - """ - - project_name: str = proto.Field( - proto.STRING, - number=1, - ) - - -class DeleteEventsResponse(proto.Message): - r"""Response message for deleting error events.""" - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/errorreporting_v1beta1/types/report_errors_service.py b/google/cloud/errorreporting_v1beta1/types/report_errors_service.py deleted file mode 100644 index 68b23ecf..00000000 --- a/google/cloud/errorreporting_v1beta1/types/report_errors_service.py +++ /dev/null @@ -1,137 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -from typing import MutableMapping, MutableSequence - -import proto # type: ignore - -from google.cloud.errorreporting_v1beta1.types import common -import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore - - -__protobuf__ = proto.module( - package="google.devtools.clouderrorreporting.v1beta1", - manifest={ - "ReportErrorEventRequest", - "ReportErrorEventResponse", - "ReportedErrorEvent", - }, -) - - -class ReportErrorEventRequest(proto.Message): - r"""A request for reporting an individual error event. - - Attributes: - project_name (str): - Required. The resource name of the Google Cloud Platform - project. Written as ``projects/{projectId}``, where - ``{projectId}`` is the `Google Cloud Platform project - ID `__. - - Example: // ``projects/my-project-123``. - event (google.cloud.errorreporting_v1beta1.types.ReportedErrorEvent): - Required. The error event to be reported. - """ - - project_name: str = proto.Field( - proto.STRING, - number=1, - ) - event: "ReportedErrorEvent" = proto.Field( - proto.MESSAGE, - number=2, - message="ReportedErrorEvent", - ) - - -class ReportErrorEventResponse(proto.Message): - r"""Response for reporting an individual error event. - Data may be added to this message in the future. - - """ - - -class ReportedErrorEvent(proto.Message): - r"""An error event which is reported to the Error Reporting - system. - - Attributes: - 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 is used. If provided, the time must not exceed the - `logs retention - period `__ - in the past, or be more than 24 hours in the future. If an - invalid time is provided, then an error is returned. - service_context (google.cloud.errorreporting_v1beta1.types.ServiceContext): - Required. The service context in which this - error has occurred. - message (str): - Required. The error message. If no - ``context.reportLocation`` is provided, the message must - contain a header (typically consisting of the exception type - name and an error message) and an exception stack trace in - one of the supported programming languages and formats. - Supported languages are Java, Python, JavaScript, Ruby, C#, - PHP, and Go. Supported stack trace formats are: - - - **Java**: Must be the return value of - ```Throwable.printStackTrace()`` `__. - - **Python**: Must be the return value of - ```traceback.format_exc()`` `__. - - **JavaScript**: Must be the value of - ```error.stack`` `__ - as returned by V8. - - **Ruby**: Must contain frames returned by - ```Exception.backtrace`` `__. - - **C#**: Must be the return value of - ```Exception.ToString()`` `__. - - **PHP**: Must be prefixed with - ``"PHP (Notice|Parse error|Fatal error|Warning): "`` and - contain the result of - ```(string)$exception`` `__. - - **Go**: Must be the return value of - ```runtime.Stack()`` `__. - context (google.cloud.errorreporting_v1beta1.types.ErrorContext): - Optional. A description of the context in - which the error occurred. - """ - - event_time: timestamp_pb2.Timestamp = proto.Field( - proto.MESSAGE, - number=1, - message=timestamp_pb2.Timestamp, - ) - service_context: common.ServiceContext = proto.Field( - proto.MESSAGE, - number=2, - message=common.ServiceContext, - ) - message: str = proto.Field( - proto.STRING, - number=3, - ) - context: common.ErrorContext = proto.Field( - proto.MESSAGE, - number=4, - message=common.ErrorContext, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/librarian.py b/librarian.py deleted file mode 100644 index 76977beb..00000000 --- a/librarian.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -import os -from pathlib import Path -import shutil - -import synthtool as s -import synthtool.gcp as gcp -from synthtool.languages import python - -# ---------------------------------------------------------------------------- -# Copy the generated client from the owl-bot staging directory -# ---------------------------------------------------------------------------- - -clean_up_generated_samples = True - -# Load the default version defined in .repo-metadata.json. -default_version = json.load(open(".repo-metadata.json", "rt")).get("default_version") - -for library in s.get_staging_dirs(default_version): - if clean_up_generated_samples: - shutil.rmtree("samples/generated_samples", ignore_errors=True) - clean_up_generated_samples = False - - s.move( - [library], - excludes=[ - "docs/index.rst", - "google/cloud/errorreporting/", - "setup.py", - "testing/constraints-3.7.txt", - "testing/constraints-3.8.txt", - "noxfile.py", - ], - ) -s.remove_staging_dirs() - -# ---------------------------------------------------------------------------- -# Add templated files -# ---------------------------------------------------------------------------- - -templated_files = gcp.CommonTemplates().py_library( - cov_level=100, - microgenerator=True, - versions=gcp.common.detect_versions(path="./google", default_first=True), -) -s.move( - templated_files, - excludes=[ - ".coveragerc", - ".github/**", - ".kokoro/**", - "docs/conf.py", - "docs/index.rst", - "testing/constraints-3.7.txt", - ], -) - -python.py_samples(skip_readmes=True) - -# run format session for all directories which have a noxfile -for noxfile in Path(".").glob("**/noxfile.py"): - s.shell.run(["nox", "-s", "blacken"], cwd=noxfile.parent, hide_output=False) diff --git a/mypy.ini b/mypy.ini deleted file mode 100644 index e0e0da2e..00000000 --- a/mypy.ini +++ /dev/null @@ -1,15 +0,0 @@ -[mypy] -python_version = 3.14 -namespace_packages = True -ignore_missing_imports = False - -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): -# Dependencies that historically lacks py.typed markers -[mypy-google.iam.*] -ignore_missing_imports = True - -# Helps mypy navigate the 'google' namespace more reliably in 3.10+ -explicit_package_bases = True - -# Performance: reuse results from previous runs to speed up 'nox' -incremental = True diff --git a/noxfile.py b/noxfile.py deleted file mode 100644 index 74f4f018..00000000 --- a/noxfile.py +++ /dev/null @@ -1,491 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# 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. - -# DO NOT EDIT THIS FILE OUTSIDE OF `.librarian/generator-input` -# The source of truth for this file is `.librarian/generator-input` - - -# Generated by synthtool. DO NOT EDIT! - -from __future__ import absolute_import - -import os -import pathlib -import re -import shutil -from typing import Dict, List -import warnings - -import nox - -FLAKE8_VERSION = "flake8==6.1.0" -BLACK_VERSION = "black[jupyter]==23.7.0" -ISORT_VERSION = "isort==5.11.0" -LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] - -DEFAULT_PYTHON_VERSION = "3.14" - -UNIT_TEST_PYTHON_VERSIONS: List[str] = [ - "3.7", - "3.8", - "3.9", - "3.10", - "3.11", - "3.12", - "3.13", - "3.14", -] -UNIT_TEST_STANDARD_DEPENDENCIES = [ - "mock", - "asyncmock", - "pytest", - "pytest-cov", - "pytest-asyncio", -] -UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] -UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = [] -UNIT_TEST_DEPENDENCIES: List[str] = [] -UNIT_TEST_EXTRAS: List[str] = [] -UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} - -SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.14"] -SYSTEM_TEST_STANDARD_DEPENDENCIES: List[str] = [ - "mock", - "pytest", - "google-cloud-testutils", -] -SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] -SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] -SYSTEM_TEST_DEPENDENCIES: List[str] = [] -SYSTEM_TEST_EXTRAS: List[str] = [] -SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} - -CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() - -nox.options.sessions = [ - "system", -] - -# Error if a python version is missing -nox.options.error_on_missing_interpreters = True - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def lint(session): - """Run linters. - - Returns a failure if the linters find linting errors or sufficiently - serious code quality issues. - """ - session.install(FLAKE8_VERSION, BLACK_VERSION) - session.run( - "black", - "--check", - *LINT_PATHS, - ) - session.run("flake8", "google", "tests") - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def blacken(session): - """Run black. Format code to uniform standard.""" - session.install(BLACK_VERSION) - session.run( - "black", - *LINT_PATHS, - ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def format(session): - """ - Run isort to sort imports. Then run black - to format code to uniform standard. - """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections - session.run( - "isort", - "--fss", - *LINT_PATHS, - ) - session.run( - "black", - *LINT_PATHS, - ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def lint_setup_py(session): - """Verify that setup.py is valid (including RST check).""" - session.install("docutils", "pygments", "setuptools") - session.run("python", "setup.py", "check", "--restructuredtext", "--strict") - - -def install_unittest_dependencies(session, *constraints): - standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES - session.install(*standard_deps, *constraints) - - if UNIT_TEST_EXTERNAL_DEPENDENCIES: - warnings.warn( - "'unit_test_external_dependencies' is deprecated. Instead, please " - "use 'unit_test_dependencies' or 'unit_test_local_dependencies'.", - DeprecationWarning, - ) - session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints) - - if UNIT_TEST_LOCAL_DEPENDENCIES: - session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints) - - if UNIT_TEST_EXTRAS_BY_PYTHON: - extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, []) - elif UNIT_TEST_EXTRAS: - extras = UNIT_TEST_EXTRAS - else: - extras = [] - - if extras: - session.install("-e", f".[{','.join(extras)}]", *constraints) - else: - session.install("-e", ".", *constraints) - - -@nox.session(python=UNIT_TEST_PYTHON_VERSIONS) -@nox.parametrize( - "protobuf_implementation", - ["python", "upb", "cpp"], -) -def unit(session, protobuf_implementation): - # Install all test dependencies, then install this package in-place. - - if protobuf_implementation == "cpp" and session.python in ( - "3.11", - "3.12", - "3.13", - "3.14", - ): - session.skip("cpp implementation is not supported in python 3.11+") - - constraints_path = str( - CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" - ) - install_unittest_dependencies(session, "-c", constraints_path) - - # TODO(https://github.com/googleapis/synthtool/issues/1976): - # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. - # The 'cpp' implementation requires Protobuf<4. - if protobuf_implementation == "cpp": - session.install("protobuf<4") - - # Run py.test against the unit tests. - session.run( - "py.test", - "--quiet", - f"--junitxml=unit_{session.python}_sponge_log.xml", - "--cov=google", - "--cov=tests/unit", - "--cov-append", - "--cov-config=.coveragerc", - "--cov-report=", - "--cov-fail-under=0", - os.path.join("tests", "unit"), - *session.posargs, - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - - -def install_systemtest_dependencies(session, *constraints): - # Use pre-release gRPC for system tests. - # Exclude version 1.52.0rc1 which has a known issue. - # See https://github.com/grpc/grpc/issues/32163 - session.install("--pre", "grpcio!=1.52.0rc1") - - session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints) - - if SYSTEM_TEST_EXTERNAL_DEPENDENCIES: - session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints) - - if SYSTEM_TEST_LOCAL_DEPENDENCIES: - session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints) - - if SYSTEM_TEST_DEPENDENCIES: - session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints) - - if SYSTEM_TEST_EXTRAS_BY_PYTHON: - extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, []) - elif SYSTEM_TEST_EXTRAS: - extras = SYSTEM_TEST_EXTRAS - else: - extras = [] - - if extras: - session.install("-e", f".[{','.join(extras)}]", *constraints) - else: - session.install("-e", ".", *constraints) - - -@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) -def system(session): - """Run the system test suite.""" - constraints_path = str( - CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" - ) - system_test_path = os.path.join("tests", "system.py") - system_test_folder_path = os.path.join("tests", "system") - - # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. - if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": - session.skip("RUN_SYSTEM_TESTS is set to false, skipping") - # 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) - # Sanity check: only run tests if found. - if not system_test_exists and not system_test_folder_exists: - session.skip("System tests were not found") - - install_systemtest_dependencies(session, "-c", constraints_path) - - # Run py.test against the system tests. - if system_test_exists: - 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", - f"--junitxml=system_{session.python}_sponge_log.xml", - system_test_folder_path, - *session.posargs, - ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -def cover(session): - """Run the final coverage report. - - This outputs the coverage report aggregating coverage from the unit - test runs (not system test runs), and then erases coverage data. - """ - session.install("coverage", "pytest-cov") - session.run("coverage", "report", "--show-missing", "--fail-under=100") - - session.run("coverage", "erase") - - -@nox.session(python="3.10") -def docs(session): - """Build the docs for this library.""" - - session.install("-e", ".") - session.install( - # We need to pin to specific versions of the `sphinxcontrib-*` packages - # which still support sphinx 4.x. - # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 - # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. - "sphinxcontrib-applehelp==1.0.4", - "sphinxcontrib-devhelp==1.0.2", - "sphinxcontrib-htmlhelp==2.0.1", - "sphinxcontrib-qthelp==1.0.3", - "sphinxcontrib-serializinghtml==1.1.5", - "sphinx==4.5.0", - "alabaster", - "recommonmark", - ) - - shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) - session.run( - "sphinx-build", - "-W", # warnings as errors - "-T", # show full traceback on exception - "-N", # no colors - "-b", - "html", - "-d", - os.path.join("docs", "_build", "doctrees", ""), - os.path.join("docs", ""), - os.path.join("docs", "_build", "html", ""), - ) - - -@nox.session(python="3.10") -def docfx(session): - """Build the docfx yaml files for this library.""" - - session.install("-e", ".") - session.install( - # We need to pin to specific versions of the `sphinxcontrib-*` packages - # which still support sphinx 4.x. - # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 - # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. - "sphinxcontrib-applehelp==1.0.4", - "sphinxcontrib-devhelp==1.0.2", - "sphinxcontrib-htmlhelp==2.0.1", - "sphinxcontrib-qthelp==1.0.3", - "sphinxcontrib-serializinghtml==1.1.5", - "gcp-sphinx-docfx-yaml", - "alabaster", - "recommonmark", - ) - - shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) - session.run( - "sphinx-build", - "-T", # show full traceback on exception - "-N", # no colors - "-D", - ( - "extensions=sphinx.ext.autodoc," - "sphinx.ext.autosummary," - "docfx_yaml.extension," - "sphinx.ext.intersphinx," - "sphinx.ext.coverage," - "sphinx.ext.napoleon," - "sphinx.ext.todo," - "sphinx.ext.viewcode," - "recommonmark" - ), - "-b", - "html", - "-d", - os.path.join("docs", "_build", "doctrees", ""), - os.path.join("docs", ""), - os.path.join("docs", "_build", "html", ""), - ) - - -@nox.session(python=DEFAULT_PYTHON_VERSION) -@nox.parametrize( - "protobuf_implementation", - ["python", "upb", "cpp"], -) -def prerelease_deps(session, protobuf_implementation): - """Run all tests with prerelease versions of dependencies installed.""" - - if protobuf_implementation == "cpp" and session.python in ( - "3.11", - "3.12", - "3.13", - "3.14", - ): - session.skip("cpp implementation is not supported in python 3.11+") - - # Install all dependencies - session.install("-e", ".[all, tests, tracing]") - unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES - session.install(*unit_deps_all) - system_deps_all = ( - SYSTEM_TEST_STANDARD_DEPENDENCIES + SYSTEM_TEST_EXTERNAL_DEPENDENCIES - ) - session.install(*system_deps_all) - - # Because we test minimum dependency versions on the minimum Python - # version, the first version we test with in the unit tests sessions has a - # constraints file containing all dependencies and extras. - with open( - CURRENT_DIRECTORY - / "testing" - / f"constraints-{UNIT_TEST_PYTHON_VERSIONS[0]}.txt", - encoding="utf-8", - ) as constraints_file: - constraints_text = constraints_file.read() - - # Ignore leading whitespace and comment lines. - constraints_deps = [ - match.group(1) - for match in re.finditer( - r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE - ) - ] - - session.install(*constraints_deps) - - prerel_deps = [ - "protobuf", - # dependency of grpc - "six", - "grpc-google-iam-v1", - "googleapis-common-protos", - "grpcio", - "grpcio-status", - "google-api-core", - "google-auth", - "proto-plus", - "google-cloud-testutils", - # dependencies of google-cloud-testutils" - "click", - ] - - for dep in prerel_deps: - session.install("--pre", "--no-deps", "--upgrade", dep) - - # Remaining dependencies - other_deps = [ - "requests", - ] - session.install(*other_deps) - - # Print out prerelease package versions - session.run( - "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" - ) - session.run("python", "-c", "import grpc; print(grpc.__version__)") - session.run("python", "-c", "import google.auth; print(google.auth.__version__)") - - session.run( - "py.test", - "tests/unit", - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - - system_test_path = os.path.join("tests", "system.py") - system_test_folder_path = os.path.join("tests", "system") - - # Only run system tests if found. - if os.path.exists(system_test_path): - session.run( - "py.test", - "--verbose", - f"--junitxml=system_{session.python}_sponge_log.xml", - system_test_path, - *session.posargs, - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) - if os.path.exists(system_test_folder_path): - session.run( - "py.test", - "--verbose", - f"--junitxml=system_{session.python}_sponge_log.xml", - system_test_folder_path, - *session.posargs, - env={ - "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, - }, - ) diff --git a/pylint.config.py b/pylint.config.py deleted file mode 100644 index 5d64b9d2..00000000 --- a/pylint.config.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""This module is used to configure gcp-devrel-py-tools run-pylint.""" - -# Library configuration - -# library_additions = {} -# library_replacements = {} - -# Test configuration - -# test_additions = copy.deepcopy(library_additions) -# test_replacements = copy.deepcopy(library_replacements) diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index f975ca75..00000000 --- a/pytest.ini +++ /dev/null @@ -1,28 +0,0 @@ -[pytest] -filterwarnings = - # treat all warnings as errors - error - # Remove once https://github.com/protocolbuffers/protobuf/issues/12186 is fixed - ignore:.*custom tp_new.*in Python 3.14:DeprecationWarning - # Remove warning once https://github.com/grpc/grpc/issues/35974 is fixed - ignore:unclosed:ResourceWarning - # Remove once https://github.com/googleapis/python-api-common-protos/pull/187/files is merged - ignore:.*pkg_resources.declare_namespace:DeprecationWarning - ignore:.*pkg_resources is deprecated as an API:DeprecationWarning - # Remove warning once https://github.com/googleapis/gapic-generator-python/issues/1939 is fixed - ignore:get_mtls_endpoint_and_cert_source is deprecated.:DeprecationWarning - # Remove warning once the minium supported version of google-cloud-logging is 2.x.x - ignore:.*Create unlinked descriptors is going to go away. Please use get/find descriptors from generated code or query the descriptor_pool.*:DeprecationWarning - # Remove tests for `credentials_file` once support for `credentials_file` is removed in `google-auth` - ignore:The `credentials_file` argument is deprecated because of a potential security risk:DeprecationWarning - # Remove after support for Python 3.7 is dropped - ignore:You are using a non-supported Python version \(3\.7:FutureWarning - # Remove after support for Python 3.8 is dropped - ignore:You are using a non-supported Python version \(3\.8:DeprecationWarning - ignore:You are using a non-supported Python version \(3\.8:FutureWarning - # Remove after support for Python 3.9 is dropped - ignore:You are using a Python version \(3\.9:FutureWarning - # Remove after support for Python 3.10 is dropped - ignore:.*You are using a Python version \(3\.10:FutureWarning - ignore:.*Please upgrade to the latest Python version.*:FutureWarning - ignore:(?s).*using a Python version.*past its end of life.*:FutureWarning diff --git a/renovate.json b/renovate.json deleted file mode 100644 index c7875c46..00000000 --- a/renovate.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": [ - "config:base", - "group:all", - ":preserveSemverRanges", - ":disableDependencyDashboard" - ], - "ignorePaths": [".pre-commit-config.yaml", ".kokoro/requirements.txt", "setup.py", ".github/workflows/unittest.yml"], - "pip_requirements": { - "fileMatch": ["requirements-test.txt", "samples/[\\S/]*constraints.txt", "samples/[\\S/]*constraints-test.txt"] - } -} diff --git a/samples/AUTHORING_GUIDE.md b/samples/AUTHORING_GUIDE.md deleted file mode 100644 index 8249522f..00000000 --- a/samples/AUTHORING_GUIDE.md +++ /dev/null @@ -1 +0,0 @@ -See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/AUTHORING_GUIDE.md \ No newline at end of file diff --git a/samples/CONTRIBUTING.md b/samples/CONTRIBUTING.md deleted file mode 100644 index f5fe2e6b..00000000 --- a/samples/CONTRIBUTING.md +++ /dev/null @@ -1 +0,0 @@ -See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/CONTRIBUTING.md \ No newline at end of file diff --git a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_get_group_async.py b/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_get_group_async.py deleted file mode 100644 index 4a0dabf5..00000000 --- a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_get_group_async.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for GetGroup -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-error-reporting - - -# [START clouderrorreporting_v1beta1_generated_ErrorGroupService_GetGroup_async] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import errorreporting_v1beta1 - - -async def sample_get_group(): - # Create a client - client = errorreporting_v1beta1.ErrorGroupServiceAsyncClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.GetGroupRequest( - group_name="group_name_value", - ) - - # Make the request - response = await client.get_group(request=request) - - # Handle the response - print(response) - -# [END clouderrorreporting_v1beta1_generated_ErrorGroupService_GetGroup_async] diff --git a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_get_group_sync.py b/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_get_group_sync.py deleted file mode 100644 index 79c76d18..00000000 --- a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_get_group_sync.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for GetGroup -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-error-reporting - - -# [START clouderrorreporting_v1beta1_generated_ErrorGroupService_GetGroup_sync] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import errorreporting_v1beta1 - - -def sample_get_group(): - # Create a client - client = errorreporting_v1beta1.ErrorGroupServiceClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.GetGroupRequest( - group_name="group_name_value", - ) - - # Make the request - response = client.get_group(request=request) - - # Handle the response - print(response) - -# [END clouderrorreporting_v1beta1_generated_ErrorGroupService_GetGroup_sync] diff --git a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_update_group_async.py b/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_update_group_async.py deleted file mode 100644 index 58a7d5b3..00000000 --- a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_update_group_async.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for UpdateGroup -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-error-reporting - - -# [START clouderrorreporting_v1beta1_generated_ErrorGroupService_UpdateGroup_async] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import errorreporting_v1beta1 - - -async def sample_update_group(): - # Create a client - client = errorreporting_v1beta1.ErrorGroupServiceAsyncClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.UpdateGroupRequest( - ) - - # Make the request - response = await client.update_group(request=request) - - # Handle the response - print(response) - -# [END clouderrorreporting_v1beta1_generated_ErrorGroupService_UpdateGroup_async] diff --git a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_update_group_sync.py b/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_update_group_sync.py deleted file mode 100644 index 9fa53da6..00000000 --- a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_group_service_update_group_sync.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for UpdateGroup -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-error-reporting - - -# [START clouderrorreporting_v1beta1_generated_ErrorGroupService_UpdateGroup_sync] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import errorreporting_v1beta1 - - -def sample_update_group(): - # Create a client - client = errorreporting_v1beta1.ErrorGroupServiceClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.UpdateGroupRequest( - ) - - # Make the request - response = client.update_group(request=request) - - # Handle the response - print(response) - -# [END clouderrorreporting_v1beta1_generated_ErrorGroupService_UpdateGroup_sync] diff --git a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_delete_events_async.py b/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_delete_events_async.py deleted file mode 100644 index 6479d386..00000000 --- a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_delete_events_async.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for DeleteEvents -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-error-reporting - - -# [START clouderrorreporting_v1beta1_generated_ErrorStatsService_DeleteEvents_async] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import errorreporting_v1beta1 - - -async def sample_delete_events(): - # Create a client - client = errorreporting_v1beta1.ErrorStatsServiceAsyncClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.DeleteEventsRequest( - project_name="project_name_value", - ) - - # Make the request - response = await client.delete_events(request=request) - - # Handle the response - print(response) - -# [END clouderrorreporting_v1beta1_generated_ErrorStatsService_DeleteEvents_async] diff --git a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_delete_events_sync.py b/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_delete_events_sync.py deleted file mode 100644 index 60dcebe9..00000000 --- a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_delete_events_sync.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for DeleteEvents -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-error-reporting - - -# [START clouderrorreporting_v1beta1_generated_ErrorStatsService_DeleteEvents_sync] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import errorreporting_v1beta1 - - -def sample_delete_events(): - # Create a client - client = errorreporting_v1beta1.ErrorStatsServiceClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.DeleteEventsRequest( - project_name="project_name_value", - ) - - # Make the request - response = client.delete_events(request=request) - - # Handle the response - print(response) - -# [END clouderrorreporting_v1beta1_generated_ErrorStatsService_DeleteEvents_sync] diff --git a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_events_async.py b/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_events_async.py deleted file mode 100644 index 3b143dca..00000000 --- a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_events_async.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListEvents -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-error-reporting - - -# [START clouderrorreporting_v1beta1_generated_ErrorStatsService_ListEvents_async] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import errorreporting_v1beta1 - - -async def sample_list_events(): - # Create a client - client = errorreporting_v1beta1.ErrorStatsServiceAsyncClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.ListEventsRequest( - project_name="project_name_value", - group_id="group_id_value", - ) - - # Make the request - page_result = client.list_events(request=request) - - # Handle the response - async for response in page_result: - print(response) - -# [END clouderrorreporting_v1beta1_generated_ErrorStatsService_ListEvents_async] diff --git a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_events_sync.py b/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_events_sync.py deleted file mode 100644 index 273d4a44..00000000 --- a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_events_sync.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListEvents -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-error-reporting - - -# [START clouderrorreporting_v1beta1_generated_ErrorStatsService_ListEvents_sync] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import errorreporting_v1beta1 - - -def sample_list_events(): - # Create a client - client = errorreporting_v1beta1.ErrorStatsServiceClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.ListEventsRequest( - project_name="project_name_value", - group_id="group_id_value", - ) - - # Make the request - page_result = client.list_events(request=request) - - # Handle the response - for response in page_result: - print(response) - -# [END clouderrorreporting_v1beta1_generated_ErrorStatsService_ListEvents_sync] diff --git a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_group_stats_async.py b/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_group_stats_async.py deleted file mode 100644 index 92ef3ed1..00000000 --- a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_group_stats_async.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListGroupStats -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-error-reporting - - -# [START clouderrorreporting_v1beta1_generated_ErrorStatsService_ListGroupStats_async] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import errorreporting_v1beta1 - - -async def sample_list_group_stats(): - # Create a client - client = errorreporting_v1beta1.ErrorStatsServiceAsyncClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.ListGroupStatsRequest( - project_name="project_name_value", - ) - - # Make the request - page_result = client.list_group_stats(request=request) - - # Handle the response - async for response in page_result: - print(response) - -# [END clouderrorreporting_v1beta1_generated_ErrorStatsService_ListGroupStats_async] diff --git a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_group_stats_sync.py b/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_group_stats_sync.py deleted file mode 100644 index ed6b7f5a..00000000 --- a/samples/generated_samples/clouderrorreporting_v1beta1_generated_error_stats_service_list_group_stats_sync.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ListGroupStats -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-error-reporting - - -# [START clouderrorreporting_v1beta1_generated_ErrorStatsService_ListGroupStats_sync] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import errorreporting_v1beta1 - - -def sample_list_group_stats(): - # Create a client - client = errorreporting_v1beta1.ErrorStatsServiceClient() - - # Initialize request argument(s) - request = errorreporting_v1beta1.ListGroupStatsRequest( - project_name="project_name_value", - ) - - # Make the request - page_result = client.list_group_stats(request=request) - - # Handle the response - for response in page_result: - print(response) - -# [END clouderrorreporting_v1beta1_generated_ErrorStatsService_ListGroupStats_sync] diff --git a/samples/generated_samples/clouderrorreporting_v1beta1_generated_report_errors_service_report_error_event_async.py b/samples/generated_samples/clouderrorreporting_v1beta1_generated_report_errors_service_report_error_event_async.py deleted file mode 100644 index b2c9d42e..00000000 --- a/samples/generated_samples/clouderrorreporting_v1beta1_generated_report_errors_service_report_error_event_async.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ReportErrorEvent -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-error-reporting - - -# [START clouderrorreporting_v1beta1_generated_ReportErrorsService_ReportErrorEvent_async] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import errorreporting_v1beta1 - - -async def sample_report_error_event(): - # Create a client - client = errorreporting_v1beta1.ReportErrorsServiceAsyncClient() - - # Initialize request argument(s) - event = errorreporting_v1beta1.ReportedErrorEvent() - event.message = "message_value" - - request = errorreporting_v1beta1.ReportErrorEventRequest( - project_name="project_name_value", - event=event, - ) - - # Make the request - response = await client.report_error_event(request=request) - - # Handle the response - print(response) - -# [END clouderrorreporting_v1beta1_generated_ReportErrorsService_ReportErrorEvent_async] diff --git a/samples/generated_samples/clouderrorreporting_v1beta1_generated_report_errors_service_report_error_event_sync.py b/samples/generated_samples/clouderrorreporting_v1beta1_generated_report_errors_service_report_error_event_sync.py deleted file mode 100644 index b413c1f6..00000000 --- a/samples/generated_samples/clouderrorreporting_v1beta1_generated_report_errors_service_report_error_event_sync.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Generated code. DO NOT EDIT! -# -# Snippet for ReportErrorEvent -# NOTE: This snippet has been automatically generated for illustrative purposes only. -# It may require modifications to work in your environment. - -# To install the latest published package dependency, execute the following: -# python3 -m pip install google-cloud-error-reporting - - -# [START clouderrorreporting_v1beta1_generated_ReportErrorsService_ReportErrorEvent_sync] -# This snippet has been automatically generated and should be regarded as a -# code template only. -# It will require modifications to work: -# - It may require correct/in-range values for request initialization. -# - It may require specifying regional endpoints when creating the service -# client as shown in: -# https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import errorreporting_v1beta1 - - -def sample_report_error_event(): - # Create a client - client = errorreporting_v1beta1.ReportErrorsServiceClient() - - # Initialize request argument(s) - event = errorreporting_v1beta1.ReportedErrorEvent() - event.message = "message_value" - - request = errorreporting_v1beta1.ReportErrorEventRequest( - project_name="project_name_value", - event=event, - ) - - # Make the request - response = client.report_error_event(request=request) - - # Handle the response - print(response) - -# [END clouderrorreporting_v1beta1_generated_ReportErrorsService_ReportErrorEvent_sync] diff --git a/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json b/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json deleted file mode 100644 index 6fff713c..00000000 --- a/samples/generated_samples/snippet_metadata_google.devtools.clouderrorreporting.v1beta1.json +++ /dev/null @@ -1,1005 +0,0 @@ -{ - "clientLibrary": { - "apis": [ - { - "id": "google.devtools.clouderrorreporting.v1beta1", - "version": "v1beta1" - } - ], - "language": "PYTHON", - "name": "google-cloud-error-reporting", - "version": "1.14.0" - }, - "snippets": [ - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.cloud.errorreporting_v1beta1.ErrorGroupServiceAsyncClient", - "shortName": "ErrorGroupServiceAsyncClient" - }, - "fullName": "google.cloud.errorreporting_v1beta1.ErrorGroupServiceAsyncClient.get_group", - "method": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService.GetGroup", - "service": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "shortName": "ErrorGroupService" - }, - "shortName": "GetGroup" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.errorreporting_v1beta1.types.GetGroupRequest" - }, - { - "name": "group_name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, Union[str, bytes]]]" - } - ], - "resultType": "google.cloud.errorreporting_v1beta1.types.ErrorGroup", - "shortName": "get_group" - }, - "description": "Sample for GetGroup", - "file": "clouderrorreporting_v1beta1_generated_error_group_service_get_group_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "clouderrorreporting_v1beta1_generated_ErrorGroupService_GetGroup_async", - "segments": [ - { - "end": 51, - "start": 27, - "type": "FULL" - }, - { - "end": 51, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 52, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "clouderrorreporting_v1beta1_generated_error_group_service_get_group_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.errorreporting_v1beta1.ErrorGroupServiceClient", - "shortName": "ErrorGroupServiceClient" - }, - "fullName": "google.cloud.errorreporting_v1beta1.ErrorGroupServiceClient.get_group", - "method": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService.GetGroup", - "service": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "shortName": "ErrorGroupService" - }, - "shortName": "GetGroup" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.errorreporting_v1beta1.types.GetGroupRequest" - }, - { - "name": "group_name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, Union[str, bytes]]]" - } - ], - "resultType": "google.cloud.errorreporting_v1beta1.types.ErrorGroup", - "shortName": "get_group" - }, - "description": "Sample for GetGroup", - "file": "clouderrorreporting_v1beta1_generated_error_group_service_get_group_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "clouderrorreporting_v1beta1_generated_ErrorGroupService_GetGroup_sync", - "segments": [ - { - "end": 51, - "start": 27, - "type": "FULL" - }, - { - "end": 51, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 52, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "clouderrorreporting_v1beta1_generated_error_group_service_get_group_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.cloud.errorreporting_v1beta1.ErrorGroupServiceAsyncClient", - "shortName": "ErrorGroupServiceAsyncClient" - }, - "fullName": "google.cloud.errorreporting_v1beta1.ErrorGroupServiceAsyncClient.update_group", - "method": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService.UpdateGroup", - "service": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "shortName": "ErrorGroupService" - }, - "shortName": "UpdateGroup" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.errorreporting_v1beta1.types.UpdateGroupRequest" - }, - { - "name": "group", - "type": "google.cloud.errorreporting_v1beta1.types.ErrorGroup" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, Union[str, bytes]]]" - } - ], - "resultType": "google.cloud.errorreporting_v1beta1.types.ErrorGroup", - "shortName": "update_group" - }, - "description": "Sample for UpdateGroup", - "file": "clouderrorreporting_v1beta1_generated_error_group_service_update_group_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "clouderrorreporting_v1beta1_generated_ErrorGroupService_UpdateGroup_async", - "segments": [ - { - "end": 50, - "start": 27, - "type": "FULL" - }, - { - "end": 50, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 44, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 47, - "start": 45, - "type": "REQUEST_EXECUTION" - }, - { - "end": 51, - "start": 48, - "type": "RESPONSE_HANDLING" - } - ], - "title": "clouderrorreporting_v1beta1_generated_error_group_service_update_group_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.errorreporting_v1beta1.ErrorGroupServiceClient", - "shortName": "ErrorGroupServiceClient" - }, - "fullName": "google.cloud.errorreporting_v1beta1.ErrorGroupServiceClient.update_group", - "method": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService.UpdateGroup", - "service": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorGroupService", - "shortName": "ErrorGroupService" - }, - "shortName": "UpdateGroup" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.errorreporting_v1beta1.types.UpdateGroupRequest" - }, - { - "name": "group", - "type": "google.cloud.errorreporting_v1beta1.types.ErrorGroup" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, Union[str, bytes]]]" - } - ], - "resultType": "google.cloud.errorreporting_v1beta1.types.ErrorGroup", - "shortName": "update_group" - }, - "description": "Sample for UpdateGroup", - "file": "clouderrorreporting_v1beta1_generated_error_group_service_update_group_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "clouderrorreporting_v1beta1_generated_ErrorGroupService_UpdateGroup_sync", - "segments": [ - { - "end": 50, - "start": 27, - "type": "FULL" - }, - { - "end": 50, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 44, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 47, - "start": 45, - "type": "REQUEST_EXECUTION" - }, - { - "end": 51, - "start": 48, - "type": "RESPONSE_HANDLING" - } - ], - "title": "clouderrorreporting_v1beta1_generated_error_group_service_update_group_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.cloud.errorreporting_v1beta1.ErrorStatsServiceAsyncClient", - "shortName": "ErrorStatsServiceAsyncClient" - }, - "fullName": "google.cloud.errorreporting_v1beta1.ErrorStatsServiceAsyncClient.delete_events", - "method": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService.DeleteEvents", - "service": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "shortName": "ErrorStatsService" - }, - "shortName": "DeleteEvents" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.errorreporting_v1beta1.types.DeleteEventsRequest" - }, - { - "name": "project_name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, Union[str, bytes]]]" - } - ], - "resultType": "google.cloud.errorreporting_v1beta1.types.DeleteEventsResponse", - "shortName": "delete_events" - }, - "description": "Sample for DeleteEvents", - "file": "clouderrorreporting_v1beta1_generated_error_stats_service_delete_events_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "clouderrorreporting_v1beta1_generated_ErrorStatsService_DeleteEvents_async", - "segments": [ - { - "end": 51, - "start": 27, - "type": "FULL" - }, - { - "end": 51, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 52, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "clouderrorreporting_v1beta1_generated_error_stats_service_delete_events_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.errorreporting_v1beta1.ErrorStatsServiceClient", - "shortName": "ErrorStatsServiceClient" - }, - "fullName": "google.cloud.errorreporting_v1beta1.ErrorStatsServiceClient.delete_events", - "method": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService.DeleteEvents", - "service": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "shortName": "ErrorStatsService" - }, - "shortName": "DeleteEvents" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.errorreporting_v1beta1.types.DeleteEventsRequest" - }, - { - "name": "project_name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, Union[str, bytes]]]" - } - ], - "resultType": "google.cloud.errorreporting_v1beta1.types.DeleteEventsResponse", - "shortName": "delete_events" - }, - "description": "Sample for DeleteEvents", - "file": "clouderrorreporting_v1beta1_generated_error_stats_service_delete_events_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "clouderrorreporting_v1beta1_generated_ErrorStatsService_DeleteEvents_sync", - "segments": [ - { - "end": 51, - "start": 27, - "type": "FULL" - }, - { - "end": 51, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 52, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "clouderrorreporting_v1beta1_generated_error_stats_service_delete_events_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.cloud.errorreporting_v1beta1.ErrorStatsServiceAsyncClient", - "shortName": "ErrorStatsServiceAsyncClient" - }, - "fullName": "google.cloud.errorreporting_v1beta1.ErrorStatsServiceAsyncClient.list_events", - "method": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService.ListEvents", - "service": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "shortName": "ErrorStatsService" - }, - "shortName": "ListEvents" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.errorreporting_v1beta1.types.ListEventsRequest" - }, - { - "name": "project_name", - "type": "str" - }, - { - "name": "group_id", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, Union[str, bytes]]]" - } - ], - "resultType": "google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListEventsAsyncPager", - "shortName": "list_events" - }, - "description": "Sample for ListEvents", - "file": "clouderrorreporting_v1beta1_generated_error_stats_service_list_events_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "clouderrorreporting_v1beta1_generated_ErrorStatsService_ListEvents_async", - "segments": [ - { - "end": 53, - "start": 27, - "type": "FULL" - }, - { - "end": 53, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 46, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 49, - "start": 47, - "type": "REQUEST_EXECUTION" - }, - { - "end": 54, - "start": 50, - "type": "RESPONSE_HANDLING" - } - ], - "title": "clouderrorreporting_v1beta1_generated_error_stats_service_list_events_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.errorreporting_v1beta1.ErrorStatsServiceClient", - "shortName": "ErrorStatsServiceClient" - }, - "fullName": "google.cloud.errorreporting_v1beta1.ErrorStatsServiceClient.list_events", - "method": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService.ListEvents", - "service": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "shortName": "ErrorStatsService" - }, - "shortName": "ListEvents" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.errorreporting_v1beta1.types.ListEventsRequest" - }, - { - "name": "project_name", - "type": "str" - }, - { - "name": "group_id", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, Union[str, bytes]]]" - } - ], - "resultType": "google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListEventsPager", - "shortName": "list_events" - }, - "description": "Sample for ListEvents", - "file": "clouderrorreporting_v1beta1_generated_error_stats_service_list_events_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "clouderrorreporting_v1beta1_generated_ErrorStatsService_ListEvents_sync", - "segments": [ - { - "end": 53, - "start": 27, - "type": "FULL" - }, - { - "end": 53, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 46, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 49, - "start": 47, - "type": "REQUEST_EXECUTION" - }, - { - "end": 54, - "start": 50, - "type": "RESPONSE_HANDLING" - } - ], - "title": "clouderrorreporting_v1beta1_generated_error_stats_service_list_events_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.cloud.errorreporting_v1beta1.ErrorStatsServiceAsyncClient", - "shortName": "ErrorStatsServiceAsyncClient" - }, - "fullName": "google.cloud.errorreporting_v1beta1.ErrorStatsServiceAsyncClient.list_group_stats", - "method": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService.ListGroupStats", - "service": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "shortName": "ErrorStatsService" - }, - "shortName": "ListGroupStats" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.errorreporting_v1beta1.types.ListGroupStatsRequest" - }, - { - "name": "project_name", - "type": "str" - }, - { - "name": "time_range", - "type": "google.cloud.errorreporting_v1beta1.types.QueryTimeRange" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, Union[str, bytes]]]" - } - ], - "resultType": "google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListGroupStatsAsyncPager", - "shortName": "list_group_stats" - }, - "description": "Sample for ListGroupStats", - "file": "clouderrorreporting_v1beta1_generated_error_stats_service_list_group_stats_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "clouderrorreporting_v1beta1_generated_ErrorStatsService_ListGroupStats_async", - "segments": [ - { - "end": 52, - "start": 27, - "type": "FULL" - }, - { - "end": 52, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 53, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "clouderrorreporting_v1beta1_generated_error_stats_service_list_group_stats_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.errorreporting_v1beta1.ErrorStatsServiceClient", - "shortName": "ErrorStatsServiceClient" - }, - "fullName": "google.cloud.errorreporting_v1beta1.ErrorStatsServiceClient.list_group_stats", - "method": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService.ListGroupStats", - "service": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ErrorStatsService", - "shortName": "ErrorStatsService" - }, - "shortName": "ListGroupStats" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.errorreporting_v1beta1.types.ListGroupStatsRequest" - }, - { - "name": "project_name", - "type": "str" - }, - { - "name": "time_range", - "type": "google.cloud.errorreporting_v1beta1.types.QueryTimeRange" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, Union[str, bytes]]]" - } - ], - "resultType": "google.cloud.errorreporting_v1beta1.services.error_stats_service.pagers.ListGroupStatsPager", - "shortName": "list_group_stats" - }, - "description": "Sample for ListGroupStats", - "file": "clouderrorreporting_v1beta1_generated_error_stats_service_list_group_stats_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "clouderrorreporting_v1beta1_generated_ErrorStatsService_ListGroupStats_sync", - "segments": [ - { - "end": 52, - "start": 27, - "type": "FULL" - }, - { - "end": 52, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 53, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "clouderrorreporting_v1beta1_generated_error_stats_service_list_group_stats_sync.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.cloud.errorreporting_v1beta1.ReportErrorsServiceAsyncClient", - "shortName": "ReportErrorsServiceAsyncClient" - }, - "fullName": "google.cloud.errorreporting_v1beta1.ReportErrorsServiceAsyncClient.report_error_event", - "method": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService.ReportErrorEvent", - "service": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - "shortName": "ReportErrorsService" - }, - "shortName": "ReportErrorEvent" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.errorreporting_v1beta1.types.ReportErrorEventRequest" - }, - { - "name": "project_name", - "type": "str" - }, - { - "name": "event", - "type": "google.cloud.errorreporting_v1beta1.types.ReportedErrorEvent" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, Union[str, bytes]]]" - } - ], - "resultType": "google.cloud.errorreporting_v1beta1.types.ReportErrorEventResponse", - "shortName": "report_error_event" - }, - "description": "Sample for ReportErrorEvent", - "file": "clouderrorreporting_v1beta1_generated_report_errors_service_report_error_event_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "clouderrorreporting_v1beta1_generated_ReportErrorsService_ReportErrorEvent_async", - "segments": [ - { - "end": 55, - "start": 27, - "type": "FULL" - }, - { - "end": 55, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 49, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 52, - "start": 50, - "type": "REQUEST_EXECUTION" - }, - { - "end": 56, - "start": 53, - "type": "RESPONSE_HANDLING" - } - ], - "title": "clouderrorreporting_v1beta1_generated_report_errors_service_report_error_event_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.errorreporting_v1beta1.ReportErrorsServiceClient", - "shortName": "ReportErrorsServiceClient" - }, - "fullName": "google.cloud.errorreporting_v1beta1.ReportErrorsServiceClient.report_error_event", - "method": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService.ReportErrorEvent", - "service": { - "fullName": "google.devtools.clouderrorreporting.v1beta1.ReportErrorsService", - "shortName": "ReportErrorsService" - }, - "shortName": "ReportErrorEvent" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.errorreporting_v1beta1.types.ReportErrorEventRequest" - }, - { - "name": "project_name", - "type": "str" - }, - { - "name": "event", - "type": "google.cloud.errorreporting_v1beta1.types.ReportedErrorEvent" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, Union[str, bytes]]]" - } - ], - "resultType": "google.cloud.errorreporting_v1beta1.types.ReportErrorEventResponse", - "shortName": "report_error_event" - }, - "description": "Sample for ReportErrorEvent", - "file": "clouderrorreporting_v1beta1_generated_report_errors_service_report_error_event_sync.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "clouderrorreporting_v1beta1_generated_ReportErrorsService_ReportErrorEvent_sync", - "segments": [ - { - "end": 55, - "start": 27, - "type": "FULL" - }, - { - "end": 55, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 49, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 52, - "start": 50, - "type": "REQUEST_EXECUTION" - }, - { - "end": 56, - "start": 53, - "type": "RESPONSE_HANDLING" - } - ], - "title": "clouderrorreporting_v1beta1_generated_report_errors_service_report_error_event_sync.py" - } - ] -} diff --git a/samples/snippets/README.md b/samples/snippets/README.md deleted file mode 100644 index b8c6e222..00000000 --- a/samples/snippets/README.md +++ /dev/null @@ -1,4 +0,0 @@ -Samples migrated -================ - -New location: https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/error_reporting diff --git a/scripts/decrypt-secrets.sh b/scripts/decrypt-secrets.sh deleted file mode 100755 index 120b0ddc..00000000 --- a/scripts/decrypt-secrets.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -# Copyright 2024 Google LLC All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -ROOT=$( dirname "$DIR" ) - -# Work from the project root. -cd $ROOT - -# Prevent it from overriding files. -# We recommend that sample authors use their own service account files and cloud project. -# In that case, they are supposed to prepare these files by themselves. -if [[ -f "testing/test-env.sh" ]] || \ - [[ -f "testing/service-account.json" ]] || \ - [[ -f "testing/client-secrets.json" ]]; then - echo "One or more target files exist, aborting." - exit 1 -fi - -# Use SECRET_MANAGER_PROJECT if set, fallback to cloud-devrel-kokoro-resources. -PROJECT_ID="${SECRET_MANAGER_PROJECT:-cloud-devrel-kokoro-resources}" - -gcloud secrets versions access latest --secret="python-docs-samples-test-env" \ - --project="${PROJECT_ID}" \ - > testing/test-env.sh -gcloud secrets versions access latest \ - --secret="python-docs-samples-service-account" \ - --project="${PROJECT_ID}" \ - > testing/service-account.json -gcloud secrets versions access latest \ - --secret="python-docs-samples-client-secrets" \ - --project="${PROJECT_ID}" \ - > testing/client-secrets.json diff --git a/scripts/readme-gen/readme_gen.py b/scripts/readme-gen/readme_gen.py deleted file mode 100644 index 8f5e248a..00000000 --- a/scripts/readme-gen/readme_gen.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Generates READMEs using configuration defined in yaml.""" - -import argparse -import io -import os -import subprocess - -import jinja2 -import yaml - - -jinja_env = jinja2.Environment( - trim_blocks=True, - loader=jinja2.FileSystemLoader( - os.path.abspath(os.path.join(os.path.dirname(__file__), "templates")) - ), - autoescape=True, -) - -README_TMPL = jinja_env.get_template("README.tmpl.rst") - - -def get_help(file): - return subprocess.check_output(["python", file, "--help"]).decode() - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument("source") - parser.add_argument("--destination", default="README.rst") - - args = parser.parse_args() - - source = os.path.abspath(args.source) - root = os.path.dirname(source) - destination = os.path.join(root, args.destination) - - jinja_env.globals["get_help"] = get_help - - with io.open(source, "r") as f: - config = yaml.load(f) - - # This allows get_help to execute in the right directory. - os.chdir(root) - - output = README_TMPL.render(config) - - with io.open(destination, "w") as f: - f.write(output) - - -if __name__ == "__main__": - main() diff --git a/scripts/readme-gen/templates/README.tmpl.rst b/scripts/readme-gen/templates/README.tmpl.rst deleted file mode 100644 index 4fd23976..00000000 --- a/scripts/readme-gen/templates/README.tmpl.rst +++ /dev/null @@ -1,87 +0,0 @@ -{# The following line is a lie. BUT! Once jinja2 is done with it, it will - become truth! #} -.. This file is automatically generated. Do not edit this file directly. - -{{product.name}} Python Samples -=============================================================================== - -.. image:: https://gstatic.com/cloudssh/images/open-btn.png - :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor={{folder}}/README.rst - - -This directory contains samples for {{product.name}}. {{product.description}} - -{{description}} - -.. _{{product.name}}: {{product.url}} - -{% if required_api_url %} -To run the sample, you need to enable the API at: {{required_api_url}} -{% endif %} - -{% if required_role %} -To run the sample, you need to have `{{required_role}}` role. -{% endif %} - -{{other_required_steps}} - -{% if setup %} -Setup -------------------------------------------------------------------------------- - -{% for section in setup %} - -{% include section + '.tmpl.rst' %} - -{% endfor %} -{% endif %} - -{% if samples %} -Samples -------------------------------------------------------------------------------- - -{% for sample in samples %} -{{sample.name}} -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -{% if not sample.hide_cloudshell_button %} -.. image:: https://gstatic.com/cloudssh/images/open-btn.png - :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor={{folder}}/{{sample.file}},{{folder}}/README.rst -{% endif %} - - -{{sample.description}} - -To run this sample: - -.. code-block:: bash - - $ python {{sample.file}} -{% if sample.show_help %} - - {{get_help(sample.file)|indent}} -{% endif %} - - -{% endfor %} -{% endif %} - -{% if cloud_client_library %} - -The client library -------------------------------------------------------------------------------- - -This sample uses the `Google Cloud Client Library for Python`_. -You can read the documentation for more details on API usage and use GitHub -to `browse the source`_ and `report issues`_. - -.. _Google Cloud Client Library for Python: - https://googlecloudplatform.github.io/google-cloud-python/ -.. _browse the source: - https://github.com/GoogleCloudPlatform/google-cloud-python -.. _report issues: - https://github.com/GoogleCloudPlatform/google-cloud-python/issues - -{% endif %} - -.. _Google Cloud SDK: https://cloud.google.com/sdk/ \ No newline at end of file diff --git a/scripts/readme-gen/templates/auth.tmpl.rst b/scripts/readme-gen/templates/auth.tmpl.rst deleted file mode 100644 index 1446b94a..00000000 --- a/scripts/readme-gen/templates/auth.tmpl.rst +++ /dev/null @@ -1,9 +0,0 @@ -Authentication -++++++++++++++ - -This sample requires you to have authentication setup. Refer to the -`Authentication Getting Started Guide`_ for instructions on setting up -credentials for applications. - -.. _Authentication Getting Started Guide: - https://cloud.google.com/docs/authentication/getting-started diff --git a/scripts/readme-gen/templates/auth_api_key.tmpl.rst b/scripts/readme-gen/templates/auth_api_key.tmpl.rst deleted file mode 100644 index 11957ce2..00000000 --- a/scripts/readme-gen/templates/auth_api_key.tmpl.rst +++ /dev/null @@ -1,14 +0,0 @@ -Authentication -++++++++++++++ - -Authentication for this service is done via an `API Key`_. To obtain an API -Key: - -1. Open the `Cloud Platform Console`_ -2. Make sure that billing is enabled for your project. -3. From the **Credentials** page, create a new **API Key** or use an existing - one for your project. - -.. _API Key: - https://developers.google.com/api-client-library/python/guide/aaa_apikeys -.. _Cloud Console: https://console.cloud.google.com/project?_ diff --git a/scripts/readme-gen/templates/install_deps.tmpl.rst b/scripts/readme-gen/templates/install_deps.tmpl.rst deleted file mode 100644 index 6f069c6c..00000000 --- a/scripts/readme-gen/templates/install_deps.tmpl.rst +++ /dev/null @@ -1,29 +0,0 @@ -Install Dependencies -++++++++++++++++++++ - -#. Clone python-docs-samples and change directory to the sample directory you want to use. - - .. code-block:: bash - - $ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git - -#. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions. - - .. _Python Development Environment Setup Guide: - https://cloud.google.com/python/setup - -#. Create a virtualenv. Samples are compatible with Python 3.7+. - - .. code-block:: bash - - $ virtualenv env - $ source env/bin/activate - -#. Install the dependencies needed to run the samples. - - .. code-block:: bash - - $ pip install -r requirements.txt - -.. _pip: https://pip.pypa.io/ -.. _virtualenv: https://virtualenv.pypa.io/ diff --git a/scripts/readme-gen/templates/install_portaudio.tmpl.rst b/scripts/readme-gen/templates/install_portaudio.tmpl.rst deleted file mode 100644 index 5ea33d18..00000000 --- a/scripts/readme-gen/templates/install_portaudio.tmpl.rst +++ /dev/null @@ -1,35 +0,0 @@ -Install PortAudio -+++++++++++++++++ - -Install `PortAudio`_. This is required by the `PyAudio`_ library to stream -audio from your computer's microphone. PyAudio depends on PortAudio for cross-platform compatibility, and is installed differently depending on the -platform. - -* For Mac OS X, you can use `Homebrew`_:: - - brew install portaudio - - **Note**: if you encounter an error when running `pip install` that indicates - it can't find `portaudio.h`, try running `pip install` with the following - flags:: - - pip install --global-option='build_ext' \ - --global-option='-I/usr/local/include' \ - --global-option='-L/usr/local/lib' \ - pyaudio - -* For Debian / Ubuntu Linux:: - - apt-get install portaudio19-dev python-all-dev - -* Windows may work without having to install PortAudio explicitly (it will get - installed with PyAudio). - -For more details, see the `PyAudio installation`_ page. - - -.. _PyAudio: https://people.csail.mit.edu/hubert/pyaudio/ -.. _PortAudio: http://www.portaudio.com/ -.. _PyAudio installation: - https://people.csail.mit.edu/hubert/pyaudio/#downloads -.. _Homebrew: http://brew.sh diff --git a/setup.py b/setup.py deleted file mode 100644 index 06588170..00000000 --- a/setup.py +++ /dev/null @@ -1,103 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# DO NOT EDIT THIS FILE OUTSIDE OF `.librarian/generator-input` -# The source of truth for this file is `.librarian/generator-input` - -import io -import os - -import setuptools # type: ignore - -package_root = os.path.abspath(os.path.dirname(__file__)) - -name = "google-cloud-error-reporting" - - -description = "Google Cloud Error Reporting API client library" - -version = {} -with open( - os.path.join(package_root, "google/cloud/error_reporting/gapic_version.py") -) as fp: - exec(fp.read(), version) -version = version["__version__"] - -if version[0] == "0": - release_status = "Development Status :: 4 - Beta" -else: - release_status = "Development Status :: 5 - Production/Stable" - -dependencies = [ - "google-cloud-logging>=1.14.0, <4.0.0", - # Exclude incompatible versions of `google-auth` - # See https://github.com/googleapis/google-cloud-python/issues/12364 - "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", - "google-api-core[grpc] >= 1.34.0, <3.0.0,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", - "grpcio >= 1.33.2, < 2.0.0", - "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", - "proto-plus >= 1.22.0, <2.0.0", - "proto-plus >= 1.22.2, <2.0.0; python_version>='3.11'", - "proto-plus >= 1.25.0, <2.0.0dev; python_version>='3.13'", - "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", -] -url = "https://github.com/googleapis/python-error-reporting" - -package_root = os.path.abspath(os.path.dirname(__file__)) - -readme_filename = os.path.join(package_root, "README.rst") -with io.open(readme_filename, encoding="utf-8") as readme_file: - readme = readme_file.read() - -packages = [ - package - for package in setuptools.find_namespace_packages() - if package.startswith("google") -] - -setuptools.setup( - name=name, - version=version, - description=description, - long_description=readme, - author="Google LLC", - author_email="googleapis-packages@google.com", - license="Apache 2.0", - url=url, - classifiers=[ - release_status, - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Programming Language :: Python :: 3.14", - "Operating System :: OS Independent", - "Topic :: Internet", - ], - platforms="Posix; MacOS X; Windows", - packages=packages, - python_requires=">=3.7", - install_requires=dependencies, - include_package_data=True, - zip_safe=False, -) diff --git a/testing/.gitignore b/testing/.gitignore deleted file mode 100644 index b05fbd63..00000000 --- a/testing/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -test-env.sh -service-account.json -client-secrets.json \ No newline at end of file diff --git a/testing/constraints-3.10.txt b/testing/constraints-3.10.txt deleted file mode 100644 index 7599dea4..00000000 --- a/testing/constraints-3.10.txt +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# This constraints file is required for unit tests. -# List all library dependencies and extras in this file. -google-api-core -google-auth -grpcio -proto-plus -protobuf -# cryptography is a direct dependency of google-auth -cryptography diff --git a/testing/constraints-3.11.txt b/testing/constraints-3.11.txt deleted file mode 100644 index 7599dea4..00000000 --- a/testing/constraints-3.11.txt +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# This constraints file is required for unit tests. -# List all library dependencies and extras in this file. -google-api-core -google-auth -grpcio -proto-plus -protobuf -# cryptography is a direct dependency of google-auth -cryptography diff --git a/testing/constraints-3.12.txt b/testing/constraints-3.12.txt deleted file mode 100644 index 7599dea4..00000000 --- a/testing/constraints-3.12.txt +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# This constraints file is required for unit tests. -# List all library dependencies and extras in this file. -google-api-core -google-auth -grpcio -proto-plus -protobuf -# cryptography is a direct dependency of google-auth -cryptography diff --git a/testing/constraints-3.13.txt b/testing/constraints-3.13.txt deleted file mode 100644 index 1e93c60e..00000000 --- a/testing/constraints-3.13.txt +++ /dev/null @@ -1,12 +0,0 @@ -# We use the constraints file for the latest Python version -# (currently this file) to check that the latest -# major versions of dependencies are supported in setup.py. -# List all library dependencies and extras in this file. -# Require the latest major version be installed for each dependency. -# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", -# Then this file should have google-cloud-foo>=1 -google-api-core>=2 -google-auth>=2 -grpcio>=1 -proto-plus>=1 -protobuf>=6 diff --git a/testing/constraints-3.14.txt b/testing/constraints-3.14.txt deleted file mode 100644 index 1e93c60e..00000000 --- a/testing/constraints-3.14.txt +++ /dev/null @@ -1,12 +0,0 @@ -# We use the constraints file for the latest Python version -# (currently this file) to check that the latest -# major versions of dependencies are supported in setup.py. -# List all library dependencies and extras in this file. -# Require the latest major version be installed for each dependency. -# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", -# Then this file should have google-cloud-foo>=1 -google-api-core>=2 -google-auth>=2 -grpcio>=1 -proto-plus>=1 -protobuf>=6 diff --git a/testing/constraints-3.7.txt b/testing/constraints-3.7.txt deleted file mode 100644 index 76b09648..00000000 --- a/testing/constraints-3.7.txt +++ /dev/null @@ -1,11 +0,0 @@ -# This constraints file is used to check that lower bounds -# are correct in setup.py -# List all library dependencies and extras in this file. -# Pin the version to the lower bound. -# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0dev", -# Then this file should have google-cloud-foo==1.14.0 -google-api-core==1.34.0 -google-auth==2.14.1 -proto-plus==1.22.0 -protobuf==3.20.2 -google-cloud-logging==1.14.0 diff --git a/testing/constraints-3.8.txt b/testing/constraints-3.8.txt deleted file mode 100644 index 3f307898..00000000 --- a/testing/constraints-3.8.txt +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -# This constraints file is required for unit tests. -# List all library dependencies and extras in this file. -google-api-core==2.14.0 -proto-plus -protobuf diff --git a/testing/constraints-3.9.txt b/testing/constraints-3.9.txt deleted file mode 100644 index 7599dea4..00000000 --- a/testing/constraints-3.9.txt +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# This constraints file is required for unit tests. -# List all library dependencies and extras in this file. -google-api-core -google-auth -grpcio -proto-plus -protobuf -# cryptography is a direct dependency of google-auth -cryptography diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index cbf94b28..00000000 --- a/tests/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/system/gapic/v1beta1/test_system_report_errors_service_v1beta1.py b/tests/system/gapic/v1beta1/test_system_report_errors_service_v1beta1.py deleted file mode 100644 index 674a6997..00000000 --- a/tests/system/gapic/v1beta1/test_system_report_errors_service_v1beta1.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import time - -from google.cloud import errorreporting_v1beta1 - - -class TestSystemReportErrorsService(object): - def test_report_error_event(self): - project_id = os.environ["PROJECT_ID"] - - client = errorreporting_v1beta1.ReportErrorsServiceClient() - project_name = f"projects/{project_id}" - message = "[MESSAGE]" - service = "[SERVICE]" - service_context = {"service": service} - file_path = "path/to/file.lang" - line_number = 42 - function_name = "meaningOfLife" - report_location = { - "file_path": file_path, - "line_number": line_number, - "function_name": function_name, - } - context = {"report_location": report_location} - event = { - "message": message, - "service_context": service_context, - "context": context, - } - response = client.report_error_event( - request={"project_name": project_name, "event": event} - ) diff --git a/tests/system/test_system.py b/tests/system/test_system.py deleted file mode 100644 index 4565a358..00000000 --- a/tests/system/test_system.py +++ /dev/null @@ -1,136 +0,0 @@ -# Copyright 2017 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import functools -import operator -import unittest -import mock - -from google.cloud import error_reporting -import google.cloud.errorreporting_v1beta1 -from google.protobuf.duration_pb2 import Duration - -from test_utils.retry import RetryResult -from test_utils.system import unique_resource_id - - -ERROR_MSG = "Error Reporting System Test" - - -def setUpModule(): - Config.CLIENT = error_reporting.Client() - - -class Config(object): - """Run-time configuration to be modified at set-up. - - This is a mutable stand-in to allow test set-up to modify - global state. - """ - - CLIENT = None - - -def _list_groups(client): - """List Error Groups from the last 60 seconds. - - This class provides a wrapper around making calls to the GAX - API. It's used by the system tests to find the appropriate error group - to verify the error was successfully reported. - - :type client: :class:`~google.cloud.error_reporting.client.Client` - :param client: The client containing a project and credentials. - - :rtype: :class:`~google.gax.ResourceIterator` - :returns: Iterable of :class:`~.google.cloud.errorreporting_v1beta1.ErrorGroupStats`. - """ - gax_api = google.cloud.errorreporting_v1beta1.ErrorStatsServiceClient( - credentials=client._credentials - ) - project_name = f"projects/{client.project}" - - time_range = google.cloud.errorreporting_v1beta1.QueryTimeRange() - time_range.period = ( - google.cloud.errorreporting_v1beta1.QueryTimeRange.Period.PERIOD_1_HOUR - ) - - duration = Duration(seconds=60 * 60) - - return gax_api.list_group_stats( - request={ - "project_name": project_name, - "time_range": time_range, - "timed_count_duration": duration, - } - ) - - -def _simulate_exception(class_name, client): - """Simulates an exception to verify it was reported. - - :type class_name: str - :param class_name: The name of a custom error class to - create (and raise). - - :type client: :class:`~google.cloud.error_reporting.client.Client` - :param client: The client that will report the exception. - """ - custom_exc = type(class_name, (RuntimeError,), {}) - try: - raise custom_exc(ERROR_MSG) - except RuntimeError: - client.report_exception() - - -def _get_error_count(class_name, client): - """Counts the number of errors in the group of the test exception. - - :type class_name: str - :param class_name: The name of a custom error class used. - - :type client: :class:`~google.cloud.error_reporting.client.Client` - :param client: The client containing a project and credentials. - - :rtype: int - :returns: Group count for errors that match ``class_name``. If no - match is found, returns :data:`None`. - """ - groups = _list_groups(client) - for group in groups: - if class_name in group.representative.message: - return group.count - - -class TestErrorReporting(unittest.TestCase): - def test_report_exception(self): - # Get a class name unique to this test case. - class_name = "RuntimeError" + unique_resource_id("_") - - # Simulate an error: group won't exist until we report - # first exception. - _simulate_exception(class_name, Config.CLIENT) - - is_one = functools.partial(operator.eq, 1) - is_one.__name__ = "is_one" # partial() has no name. - retry = RetryResult(is_one, max_tries=8) - wrapped_get_count = retry(_get_error_count) - - error_count = wrapped_get_count(class_name, Config.CLIENT) - self.assertEqual(error_count, 1) - - def test_report_exception_no_grpc(self): - with mock.patch.dict( - "os.environ", {"GOOGLE_CLOUD_DISABLE_GRPC": "true"}, clear=True - ): - self.test_report_exception() diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py deleted file mode 100644 index cbf94b28..00000000 --- a/tests/unit/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/__init__.py b/tests/unit/gapic/__init__.py deleted file mode 100644 index cbf94b28..00000000 --- a/tests/unit/gapic/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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/__init__.py b/tests/unit/gapic/errorreporting_v1beta1/__init__.py deleted file mode 100644 index cbf94b28..00000000 --- a/tests/unit/gapic/errorreporting_v1beta1/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 deleted file mode 100644 index 10807479..00000000 --- a/tests/unit/gapic/errorreporting_v1beta1/test_error_group_service.py +++ /dev/null @@ -1,3625 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import os - -# try/except added for compatibility with python < 3.8 -try: - from unittest import mock - from unittest.mock import AsyncMock # pragma: NO COVER -except ImportError: # pragma: NO COVER - import mock - -import grpc -from grpc.experimental import aio -from collections.abc import Iterable, AsyncIterable -from google.protobuf import json_format -import json -import math -import pytest -from collections.abc import Sequence, Mapping -from google.api_core import api_core_version -from proto.marshal.rules.dates import DurationRule, TimestampRule -from proto.marshal.rules import wrappers -from requests import Response -from requests import Request, PreparedRequest -from requests.sessions import Session -from google.protobuf import json_format - -try: - from google.auth.aio import credentials as ga_credentials_async - - HAS_GOOGLE_AUTH_AIO = True -except ImportError: # pragma: NO COVER - HAS_GOOGLE_AUTH_AIO = False - -from google.api_core import client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers -from google.api_core import grpc_helpers_async -from google.api_core import path_template -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.cloud.errorreporting_v1beta1.services.error_group_service import ( - ErrorGroupServiceAsyncClient, -) -from google.cloud.errorreporting_v1beta1.services.error_group_service import ( - ErrorGroupServiceClient, -) -from google.cloud.errorreporting_v1beta1.services.error_group_service import transports -from google.cloud.errorreporting_v1beta1.types import common -from google.cloud.errorreporting_v1beta1.types import error_group_service -from google.oauth2 import service_account -import google.auth - - -CRED_INFO_JSON = { - "credential_source": "/path/to/file", - "credential_type": "service account credentials", - "principal": "service-account@example.com", -} -CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) - - -async def mock_async_gen(data, chunk_size=1): - for i in range(0, len(data)): # pragma: NO COVER - chunk = data[i : i + chunk_size] - yield chunk.encode("utf-8") - - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - - -# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. -# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. -def async_anonymous_credentials(): - if HAS_GOOGLE_AUTH_AIO: - return ga_credentials_async.AnonymousCredentials() - return ga_credentials.AnonymousCredentials() - - -# If default endpoint is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint(client): - return ( - "foo.googleapis.com" - if ("localhost" in client.DEFAULT_ENDPOINT) - else client.DEFAULT_ENDPOINT - ) - - -# If default endpoint template is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint template so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint_template(client): - return ( - "test.{UNIVERSE_DOMAIN}" - if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) - else client._DEFAULT_ENDPOINT_TEMPLATE - ) - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert ErrorGroupServiceClient._get_default_mtls_endpoint(None) is None - assert ( - ErrorGroupServiceClient._get_default_mtls_endpoint(api_endpoint) - == api_mtls_endpoint - ) - assert ( - ErrorGroupServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) - == api_mtls_endpoint - ) - assert ( - ErrorGroupServiceClient._get_default_mtls_endpoint(sandbox_endpoint) - == sandbox_mtls_endpoint - ) - assert ( - ErrorGroupServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) - == sandbox_mtls_endpoint - ) - assert ( - ErrorGroupServiceClient._get_default_mtls_endpoint(non_googleapi) - == non_googleapi - ) - - -def test__read_environment_variables(): - assert ErrorGroupServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert ErrorGroupServiceClient._read_environment_variables() == ( - True, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - assert ErrorGroupServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with pytest.raises(ValueError) as excinfo: - ErrorGroupServiceClient._read_environment_variables() - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - else: - assert ErrorGroupServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - assert ErrorGroupServiceClient._read_environment_variables() == ( - False, - "never", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - assert ErrorGroupServiceClient._read_environment_variables() == ( - False, - "always", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): - assert ErrorGroupServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - ErrorGroupServiceClient._read_environment_variables() - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): - assert ErrorGroupServiceClient._read_environment_variables() == ( - False, - "auto", - "foo.com", - ) - - -def test_use_client_cert_effective(): - # Test case 1: Test when `should_use_client_cert` returns True. - # We mock the `should_use_client_cert` function to simulate a scenario where - # the google-auth library supports automatic mTLS and determines that a - # client certificate should be used. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch( - "google.auth.transport.mtls.should_use_client_cert", return_value=True - ): - assert ErrorGroupServiceClient._use_client_cert_effective() is True - - # Test case 2: Test when `should_use_client_cert` returns False. - # We mock the `should_use_client_cert` function to simulate a scenario where - # the google-auth library supports automatic mTLS and determines that a - # client certificate should NOT be used. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch( - "google.auth.transport.mtls.should_use_client_cert", return_value=False - ): - assert ErrorGroupServiceClient._use_client_cert_effective() is False - - # Test case 3: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert ErrorGroupServiceClient._use_client_cert_effective() is True - - # Test case 4: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} - ): - assert ErrorGroupServiceClient._use_client_cert_effective() is False - - # Test case 5: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): - assert ErrorGroupServiceClient._use_client_cert_effective() is True - - # Test case 6: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} - ): - assert ErrorGroupServiceClient._use_client_cert_effective() is False - - # Test case 7: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): - assert ErrorGroupServiceClient._use_client_cert_effective() is True - - # Test case 8: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} - ): - assert ErrorGroupServiceClient._use_client_cert_effective() is False - - # Test case 9: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set. - # In this case, the method should return False, which is the default value. - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, clear=True): - assert ErrorGroupServiceClient._use_client_cert_effective() is False - - # Test case 10: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. - # The method should raise a ValueError as the environment variable must be either - # "true" or "false". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} - ): - with pytest.raises(ValueError): - ErrorGroupServiceClient._use_client_cert_effective() - - # Test case 11: Test when `should_use_client_cert` is available and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. - # The method should return False as the environment variable is set to an invalid value. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} - ): - assert ErrorGroupServiceClient._use_client_cert_effective() is False - - # Test case 12: Test when `should_use_client_cert` is available and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also, - # the GOOGLE_API_CONFIG environment variable is unset. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}): - with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}): - assert ErrorGroupServiceClient._use_client_cert_effective() is False - - -def test__get_client_cert_source(): - mock_provided_cert_source = mock.Mock() - mock_default_cert_source = mock.Mock() - - assert ErrorGroupServiceClient._get_client_cert_source(None, False) is None - assert ( - ErrorGroupServiceClient._get_client_cert_source( - mock_provided_cert_source, False - ) - is None - ) - assert ( - ErrorGroupServiceClient._get_client_cert_source(mock_provided_cert_source, True) - == mock_provided_cert_source - ) - - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", return_value=True - ): - with mock.patch( - "google.auth.transport.mtls.default_client_cert_source", - return_value=mock_default_cert_source, - ): - assert ( - ErrorGroupServiceClient._get_client_cert_source(None, True) - is mock_default_cert_source - ) - assert ( - ErrorGroupServiceClient._get_client_cert_source( - mock_provided_cert_source, "true" - ) - is mock_provided_cert_source - ) - - -@mock.patch.object( - ErrorGroupServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorGroupServiceClient), -) -@mock.patch.object( - ErrorGroupServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorGroupServiceAsyncClient), -) -def test__get_api_endpoint(): - api_override = "foo.com" - mock_client_cert_source = mock.Mock() - default_universe = ErrorGroupServiceClient._DEFAULT_UNIVERSE - default_endpoint = ErrorGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=default_universe - ) - mock_universe = "bar.com" - mock_endpoint = ErrorGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=mock_universe - ) - - assert ( - ErrorGroupServiceClient._get_api_endpoint( - api_override, mock_client_cert_source, default_universe, "always" - ) - == api_override - ) - assert ( - ErrorGroupServiceClient._get_api_endpoint( - None, mock_client_cert_source, default_universe, "auto" - ) - == ErrorGroupServiceClient.DEFAULT_MTLS_ENDPOINT - ) - assert ( - ErrorGroupServiceClient._get_api_endpoint(None, None, default_universe, "auto") - == default_endpoint - ) - assert ( - ErrorGroupServiceClient._get_api_endpoint( - None, None, default_universe, "always" - ) - == ErrorGroupServiceClient.DEFAULT_MTLS_ENDPOINT - ) - assert ( - ErrorGroupServiceClient._get_api_endpoint( - None, mock_client_cert_source, default_universe, "always" - ) - == ErrorGroupServiceClient.DEFAULT_MTLS_ENDPOINT - ) - assert ( - ErrorGroupServiceClient._get_api_endpoint(None, None, mock_universe, "never") - == mock_endpoint - ) - assert ( - ErrorGroupServiceClient._get_api_endpoint(None, None, default_universe, "never") - == default_endpoint - ) - - with pytest.raises(MutualTLSChannelError) as excinfo: - ErrorGroupServiceClient._get_api_endpoint( - None, mock_client_cert_source, mock_universe, "auto" - ) - assert ( - str(excinfo.value) - == "mTLS is not supported in any universe other than googleapis.com." - ) - - -def test__get_universe_domain(): - client_universe_domain = "foo.com" - universe_domain_env = "bar.com" - - assert ( - ErrorGroupServiceClient._get_universe_domain( - client_universe_domain, universe_domain_env - ) - == client_universe_domain - ) - assert ( - ErrorGroupServiceClient._get_universe_domain(None, universe_domain_env) - == universe_domain_env - ) - assert ( - ErrorGroupServiceClient._get_universe_domain(None, None) - == ErrorGroupServiceClient._DEFAULT_UNIVERSE - ) - - with pytest.raises(ValueError) as excinfo: - ErrorGroupServiceClient._get_universe_domain("", None) - assert str(excinfo.value) == "Universe Domain cannot be an empty string." - - -@pytest.mark.parametrize( - "error_code,cred_info_json,show_cred_info", - [ - (401, CRED_INFO_JSON, True), - (403, CRED_INFO_JSON, True), - (404, CRED_INFO_JSON, True), - (500, CRED_INFO_JSON, False), - (401, None, False), - (403, None, False), - (404, None, False), - (500, None, False), - ], -) -def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): - cred = mock.Mock(["get_cred_info"]) - cred.get_cred_info = mock.Mock(return_value=cred_info_json) - client = ErrorGroupServiceClient(credentials=cred) - client._transport._credentials = cred - - error = core_exceptions.GoogleAPICallError("message", details=["foo"]) - error.code = error_code - - client._add_cred_info_for_auth_errors(error) - if show_cred_info: - assert error.details == ["foo", CRED_INFO_STRING] - else: - assert error.details == ["foo"] - - -@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) -def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): - cred = mock.Mock([]) - assert not hasattr(cred, "get_cred_info") - client = ErrorGroupServiceClient(credentials=cred) - client._transport._credentials = cred - - error = core_exceptions.GoogleAPICallError("message", details=[]) - error.code = error_code - - client._add_cred_info_for_auth_errors(error) - assert error.details == [] - - -@pytest.mark.parametrize( - "client_class,transport_name", - [ - (ErrorGroupServiceClient, "grpc"), - (ErrorGroupServiceAsyncClient, "grpc_asyncio"), - (ErrorGroupServiceClient, "rest"), - ], -) -def test_error_group_service_client_from_service_account_info( - client_class, transport_name -): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object( - service_account.Credentials, "from_service_account_info" - ) as factory: - factory.return_value = creds - info = {"valid": True} - client = client_class.from_service_account_info(info, transport=transport_name) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == ( - "clouderrorreporting.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://clouderrorreporting.googleapis.com" - ) - - -@pytest.mark.parametrize( - "transport_class,transport_name", - [ - (transports.ErrorGroupServiceGrpcTransport, "grpc"), - (transports.ErrorGroupServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (transports.ErrorGroupServiceRestTransport, "rest"), - ], -) -def test_error_group_service_client_service_account_always_use_jwt( - transport_class, transport_name -): - with mock.patch.object( - service_account.Credentials, "with_always_use_jwt_access", create=True - ) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=True) - use_jwt.assert_called_once_with(True) - - with mock.patch.object( - service_account.Credentials, "with_always_use_jwt_access", create=True - ) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=False) - use_jwt.assert_not_called() - - -@pytest.mark.parametrize( - "client_class,transport_name", - [ - (ErrorGroupServiceClient, "grpc"), - (ErrorGroupServiceAsyncClient, "grpc_asyncio"), - (ErrorGroupServiceClient, "rest"), - ], -) -def test_error_group_service_client_from_service_account_file( - client_class, transport_name -): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object( - service_account.Credentials, "from_service_account_file" - ) as factory: - factory.return_value = creds - client = client_class.from_service_account_file( - "dummy/file/path.json", transport=transport_name - ) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - client = client_class.from_service_account_json( - "dummy/file/path.json", transport=transport_name - ) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == ( - "clouderrorreporting.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://clouderrorreporting.googleapis.com" - ) - - -def test_error_group_service_client_get_transport_class(): - transport = ErrorGroupServiceClient.get_transport_class() - available_transports = [ - transports.ErrorGroupServiceGrpcTransport, - transports.ErrorGroupServiceRestTransport, - ] - assert transport in available_transports - - transport = ErrorGroupServiceClient.get_transport_class("grpc") - assert transport == transports.ErrorGroupServiceGrpcTransport - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name", - [ - (ErrorGroupServiceClient, transports.ErrorGroupServiceGrpcTransport, "grpc"), - ( - ErrorGroupServiceAsyncClient, - transports.ErrorGroupServiceGrpcAsyncIOTransport, - "grpc_asyncio", - ), - (ErrorGroupServiceClient, transports.ErrorGroupServiceRestTransport, "rest"), - ], -) -@mock.patch.object( - ErrorGroupServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorGroupServiceClient), -) -@mock.patch.object( - ErrorGroupServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorGroupServiceAsyncClient), -) -def test_error_group_service_client_client_options( - client_class, transport_class, transport_name -): - # Check that if channel is provided we won't create a new one. - with mock.patch.object(ErrorGroupServiceClient, "get_transport_class") as gtc: - transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) - client = client_class(transport=transport) - gtc.assert_not_called() - - # Check that if channel is provided via str we will create a new one. - with mock.patch.object(ErrorGroupServiceClient, "get_transport_class") as gtc: - client = client_class(transport=transport_name) - gtc.assert_called() - - # Check the case api_endpoint is provided. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - client = client_class(transport=transport_name) - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - # Check the case api_endpoint is provided - options = client_options.ClientOptions( - api_audience="https://language.googleapis.com" - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience="https://language.googleapis.com", - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,use_client_cert_env", - [ - ( - ErrorGroupServiceClient, - transports.ErrorGroupServiceGrpcTransport, - "grpc", - "true", - ), - ( - ErrorGroupServiceAsyncClient, - transports.ErrorGroupServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "true", - ), - ( - ErrorGroupServiceClient, - transports.ErrorGroupServiceGrpcTransport, - "grpc", - "false", - ), - ( - ErrorGroupServiceAsyncClient, - transports.ErrorGroupServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "false", - ), - ( - ErrorGroupServiceClient, - transports.ErrorGroupServiceRestTransport, - "rest", - "true", - ), - ( - ErrorGroupServiceClient, - transports.ErrorGroupServiceRestTransport, - "rest", - "false", - ), - ], -) -@mock.patch.object( - ErrorGroupServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorGroupServiceClient), -) -@mock.patch.object( - ErrorGroupServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorGroupServiceAsyncClient), -) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_error_group_service_client_mtls_env_auto( - client_class, transport_class, transport_name, use_client_cert_env -): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - options = client_options.ClientOptions( - client_cert_source=client_cert_source_callback - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - - if use_client_cert_env == "false": - expected_client_cert_source = None - expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ) - else: - expected_client_cert_source = client_cert_source_callback - expected_host = client.DEFAULT_MTLS_ENDPOINT - - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, - ): - with mock.patch( - "google.auth.transport.mtls.default_client_cert_source", - return_value=client_cert_source_callback, - ): - if use_client_cert_env == "false": - expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ) - expected_client_cert_source = None - else: - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_client_cert_source = client_cert_source_callback - - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, - ): - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize( - "client_class", [ErrorGroupServiceClient, ErrorGroupServiceAsyncClient] -) -@mock.patch.object( - ErrorGroupServiceClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(ErrorGroupServiceClient), -) -@mock.patch.object( - ErrorGroupServiceAsyncClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(ErrorGroupServiceAsyncClient), -) -def test_error_group_service_client_get_mtls_endpoint_and_cert_source(client_class): - mock_client_cert_source = mock.Mock() - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint - ) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( - options - ) - assert api_endpoint == mock_api_endpoint - assert cert_source == mock_client_cert_source - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint - ) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( - options - ) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "Unsupported". - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, - api_endpoint=mock_api_endpoint, - ) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( - options - ) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset. - test_cases = [ - ( - # With workloads present in config, mTLS is enabled. - { - "version": 1, - "cert_configs": { - "workload": { - "cert_path": "path/to/cert/file", - "key_path": "path/to/key/file", - } - }, - }, - mock_client_cert_source, - ), - ( - # With workloads not present in config, mTLS is disabled. - { - "version": 1, - "cert_configs": {}, - }, - None, - ), - ] - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - for config_data, expected_cert_source in test_cases: - env = os.environ.copy() - env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) - with mock.patch.dict(os.environ, env, clear=True): - config_filename = "mock_certificate_config.json" - config_file_content = json.dumps(config_data) - m = mock.mock_open(read_data=config_file_content) - with mock.patch("builtins.open", m): - with mock.patch.dict( - os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} - ): - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, - api_endpoint=mock_api_endpoint, - ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is expected_cert_source - - # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). - test_cases = [ - ( - # With workloads present in config, mTLS is enabled. - { - "version": 1, - "cert_configs": { - "workload": { - "cert_path": "path/to/cert/file", - "key_path": "path/to/key/file", - } - }, - }, - mock_client_cert_source, - ), - ( - # With workloads not present in config, mTLS is disabled. - { - "version": 1, - "cert_configs": {}, - }, - None, - ), - ] - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - for config_data, expected_cert_source in test_cases: - env = os.environ.copy() - env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") - with mock.patch.dict(os.environ, env, clear=True): - config_filename = "mock_certificate_config.json" - config_file_content = json.dumps(config_data) - m = mock.mock_open(read_data=config_file_content) - with mock.patch("builtins.open", m): - with mock.patch.dict( - os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} - ): - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, - api_endpoint=mock_api_endpoint, - ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is expected_cert_source - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, - ): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, - ): - with mock.patch( - "google.auth.transport.mtls.default_client_cert_source", - return_value=mock_client_cert_source, - ): - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source == mock_client_cert_source - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - -@pytest.mark.parametrize( - "client_class", [ErrorGroupServiceClient, ErrorGroupServiceAsyncClient] -) -@mock.patch.object( - ErrorGroupServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorGroupServiceClient), -) -@mock.patch.object( - ErrorGroupServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorGroupServiceAsyncClient), -) -def test_error_group_service_client_client_api_endpoint(client_class): - mock_client_cert_source = client_cert_source_callback - api_override = "foo.com" - default_universe = ErrorGroupServiceClient._DEFAULT_UNIVERSE - default_endpoint = ErrorGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=default_universe - ) - mock_universe = "bar.com" - mock_endpoint = ErrorGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=mock_universe - ) - - # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", - # use ClientOptions.api_endpoint as the api endpoint regardless. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch( - "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" - ): - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, api_endpoint=api_override - ) - client = client_class( - client_options=options, - credentials=ga_credentials.AnonymousCredentials(), - ) - assert client.api_endpoint == api_override - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", - # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - - # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), - # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, - # and ClientOptions.universe_domain="bar.com", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. - options = client_options.ClientOptions() - universe_exists = hasattr(options, "universe_domain") - if universe_exists: - options = client_options.ClientOptions(universe_domain=mock_universe) - client = client_class( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - else: - client = client_class( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - assert client.api_endpoint == ( - mock_endpoint if universe_exists else default_endpoint - ) - assert client.universe_domain == ( - mock_universe if universe_exists else default_universe - ) - - # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - options = client_options.ClientOptions() - if hasattr(options, "universe_domain"): - delattr(options, "universe_domain") - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - assert client.api_endpoint == default_endpoint - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name", - [ - (ErrorGroupServiceClient, transports.ErrorGroupServiceGrpcTransport, "grpc"), - ( - ErrorGroupServiceAsyncClient, - transports.ErrorGroupServiceGrpcAsyncIOTransport, - "grpc_asyncio", - ), - (ErrorGroupServiceClient, transports.ErrorGroupServiceRestTransport, "rest"), - ], -) -def test_error_group_service_client_client_options_scopes( - client_class, transport_class, transport_name -): - # Check the case scopes are provided. - options = client_options.ClientOptions( - scopes=["1", "2"], - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=["1", "2"], - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,grpc_helpers", - [ - ( - ErrorGroupServiceClient, - transports.ErrorGroupServiceGrpcTransport, - "grpc", - grpc_helpers, - ), - ( - ErrorGroupServiceAsyncClient, - transports.ErrorGroupServiceGrpcAsyncIOTransport, - "grpc_asyncio", - grpc_helpers_async, - ), - ( - ErrorGroupServiceClient, - transports.ErrorGroupServiceRestTransport, - "rest", - None, - ), - ], -) -def test_error_group_service_client_client_options_credentials_file( - client_class, transport_class, transport_name, grpc_helpers -): - # Check the case credentials file is provided. - options = client_options.ClientOptions(credentials_file="credentials.json") - - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -def test_error_group_service_client_client_options_from_dict(): - with mock.patch( - "google.cloud.errorreporting_v1beta1.services.error_group_service.transports.ErrorGroupServiceGrpcTransport.__init__" - ) as grpc_transport: - grpc_transport.return_value = None - client = ErrorGroupServiceClient( - client_options={"api_endpoint": "squid.clam.whelk"} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,grpc_helpers", - [ - ( - ErrorGroupServiceClient, - transports.ErrorGroupServiceGrpcTransport, - "grpc", - grpc_helpers, - ), - ( - ErrorGroupServiceAsyncClient, - transports.ErrorGroupServiceGrpcAsyncIOTransport, - "grpc_asyncio", - grpc_helpers_async, - ), - ], -) -def test_error_group_service_client_create_channel_credentials_file( - client_class, transport_class, transport_name, grpc_helpers -): - # Check the case credentials file is provided. - options = client_options.ClientOptions(credentials_file="credentials.json") - - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # test that the credentials from file are saved and used as the credentials. - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch.object( - google.auth, "default", autospec=True - ) as adc, mock.patch.object( - grpc_helpers, "create_channel" - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - file_creds = ga_credentials.AnonymousCredentials() - load_creds.return_value = (file_creds, None) - adc.return_value = (creds, None) - client = client_class(client_options=options, transport=transport_name) - create_channel.assert_called_with( - "clouderrorreporting.googleapis.com:443", - credentials=file_creds, - credentials_file=None, - quota_project_id=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - scopes=None, - default_host="clouderrorreporting.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize( - "request_type", - [ - error_group_service.GetGroupRequest, - dict, - ], -) -def test_get_group(request_type, transport: str = "grpc"): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_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", - resolution_status=common.ResolutionStatus.OPEN, - ) - response = client.get_group(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = error_group_service.GetGroupRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, common.ErrorGroup) - assert response.name == "name_value" - assert response.group_id == "group_id_value" - assert response.resolution_status == common.ResolutionStatus.OPEN - - -def test_get_group_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = error_group_service.GetGroupRequest( - group_name="group_name_value", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_group), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.get_group(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == error_group_service.GetGroupRequest( - group_name="group_name_value", - ) - - -def test_get_group_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_group in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.get_group] = mock_rpc - request = {} - client.get_group(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.get_group(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -@pytest.mark.asyncio -async def test_get_group_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._client._transport.get_group - in client._client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[ - client._client._transport.get_group - ] = mock_rpc - - request = {} - await client.get_group(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.get_group(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -@pytest.mark.asyncio -async def test_get_group_async( - transport: str = "grpc_asyncio", request_type=error_group_service.GetGroupRequest -): - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_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", - resolution_status=common.ResolutionStatus.OPEN, - ) - ) - response = await client.get_group(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = error_group_service.GetGroupRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, common.ErrorGroup) - assert response.name == "name_value" - 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(): - await test_get_group_async(request_type=dict) - - -def test_get_group_field_headers(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = error_group_service.GetGroupRequest() - - request.group_name = "group_name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_group), "__call__") as call: - call.return_value = common.ErrorGroup() - client.get_group(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "group_name=group_name_value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_get_group_field_headers_async(): - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = error_group_service.GetGroupRequest() - - request.group_name = "group_name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.get_group), "__call__") as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(common.ErrorGroup()) - await client.get_group(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "group_name=group_name_value", - ) in kw["metadata"] - - -def test_get_group_flattened(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - 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() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.get_group( - group_name="group_name_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].group_name - mock_val = "group_name_value" - assert arg == mock_val - - -def test_get_group_flattened_error(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_group( - error_group_service.GetGroupRequest(), - group_name="group_name_value", - ) - - -@pytest.mark.asyncio -async def test_get_group_flattened_async(): - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - 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() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(common.ErrorGroup()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.get_group( - group_name="group_name_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].group_name - mock_val = "group_name_value" - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_get_group_flattened_error_async(): - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.get_group( - error_group_service.GetGroupRequest(), - group_name="group_name_value", - ) - - -@pytest.mark.parametrize( - "request_type", - [ - error_group_service.UpdateGroupRequest, - dict, - ], -) -def test_update_group(request_type, transport: str = "grpc"): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_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", - resolution_status=common.ResolutionStatus.OPEN, - ) - response = client.update_group(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = error_group_service.UpdateGroupRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, common.ErrorGroup) - assert response.name == "name_value" - assert response.group_id == "group_id_value" - assert response.resolution_status == common.ResolutionStatus.OPEN - - -def test_update_group_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = error_group_service.UpdateGroupRequest() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_group), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.update_group(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == error_group_service.UpdateGroupRequest() - - -def test_update_group_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.update_group in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.update_group] = mock_rpc - request = {} - client.update_group(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.update_group(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -@pytest.mark.asyncio -async def test_update_group_async_use_cached_wrapped_rpc( - transport: str = "grpc_asyncio", -): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._client._transport.update_group - in client._client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[ - client._client._transport.update_group - ] = mock_rpc - - request = {} - await client.update_group(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.update_group(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -@pytest.mark.asyncio -async def test_update_group_async( - transport: str = "grpc_asyncio", request_type=error_group_service.UpdateGroupRequest -): - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_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", - resolution_status=common.ResolutionStatus.OPEN, - ) - ) - response = await client.update_group(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = error_group_service.UpdateGroupRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, common.ErrorGroup) - assert response.name == "name_value" - 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(): - await test_update_group_async(request_type=dict) - - -def test_update_group_field_headers(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = error_group_service.UpdateGroupRequest() - - request.group.name = "name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_group), "__call__") as call: - call.return_value = common.ErrorGroup() - client.update_group(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "group.name=name_value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_update_group_field_headers_async(): - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = error_group_service.UpdateGroupRequest() - - request.group.name = "name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.update_group), "__call__") as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(common.ErrorGroup()) - await client.update_group(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "group.name=name_value", - ) in kw["metadata"] - - -def test_update_group_flattened(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - 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() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.update_group( - group=common.ErrorGroup(name="name_value"), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].group - mock_val = common.ErrorGroup(name="name_value") - assert arg == mock_val - - -def test_update_group_flattened_error(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_group( - error_group_service.UpdateGroupRequest(), - group=common.ErrorGroup(name="name_value"), - ) - - -@pytest.mark.asyncio -async def test_update_group_flattened_async(): - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - 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() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(common.ErrorGroup()) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.update_group( - group=common.ErrorGroup(name="name_value"), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].group - mock_val = common.ErrorGroup(name="name_value") - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_update_group_flattened_error_async(): - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.update_group( - error_group_service.UpdateGroupRequest(), - group=common.ErrorGroup(name="name_value"), - ) - - -def test_get_group_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.get_group in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.get_group] = mock_rpc - - request = {} - client.get_group(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.get_group(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_get_group_rest_required_fields( - request_type=error_group_service.GetGroupRequest, -): - transport_class = transports.ErrorGroupServiceRestTransport - - request_init = {} - request_init["group_name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_group._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["groupName"] = "group_name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_group._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "groupName" in jsonified_request - assert jsonified_request["groupName"] == "group_name_value" - - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = common.ErrorGroup() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = common.ErrorGroup.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - response = client.get_group(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_get_group_rest_unset_required_fields(): - transport = transports.ErrorGroupServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.get_group._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("groupName",))) - - -def test_get_group_rest_flattened(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = common.ErrorGroup() - - # get arguments that satisfy an http rule for this method - sample_request = {"group_name": "projects/sample1/groups/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - group_name="group_name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = common.ErrorGroup.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.get_group(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1beta1/{group_name=projects/*/groups/*}" % client.transport._host, - args[1], - ) - - -def test_get_group_rest_flattened_error(transport: str = "rest"): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_group( - error_group_service.GetGroupRequest(), - group_name="group_name_value", - ) - - -def test_update_group_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.update_group in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.update_group] = mock_rpc - - request = {} - client.update_group(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.update_group(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_update_group_rest_required_fields( - request_type=error_group_service.UpdateGroupRequest, -): - transport_class = transports.ErrorGroupServiceRestTransport - - request_init = {} - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_group._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_group._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = common.ErrorGroup() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "put", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = common.ErrorGroup.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - response = client.update_group(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_update_group_rest_unset_required_fields(): - transport = transports.ErrorGroupServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.update_group._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("group",))) - - -def test_update_group_rest_flattened(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = common.ErrorGroup() - - # get arguments that satisfy an http rule for this method - sample_request = {"group": {"name": "projects/sample1/groups/sample2"}} - - # get truthy value for each flattened field - mock_args = dict( - group=common.ErrorGroup(name="name_value"), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = common.ErrorGroup.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.update_group(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1beta1/{group.name=projects/*/groups/*}" % client.transport._host, - args[1], - ) - - -def test_update_group_rest_flattened_error(transport: str = "rest"): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_group( - error_group_service.UpdateGroupRequest(), - group=common.ErrorGroup(name="name_value"), - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.ErrorGroupServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.ErrorGroupServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ErrorGroupServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.ErrorGroupServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ErrorGroupServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ErrorGroupServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.ErrorGroupServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ErrorGroupServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.ErrorGroupServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = ErrorGroupServiceClient(transport=transport) - assert client.transport is transport - - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.ErrorGroupServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.ErrorGroupServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ErrorGroupServiceGrpcTransport, - transports.ErrorGroupServiceGrpcAsyncIOTransport, - transports.ErrorGroupServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - -def test_transport_kind_grpc(): - transport = ErrorGroupServiceClient.get_transport_class("grpc")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "grpc" - - -def test_initialize_client_w_grpc(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_group_empty_call_grpc(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_group), "__call__") as call: - call.return_value = common.ErrorGroup() - client.get_group(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_group_service.GetGroupRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_group_empty_call_grpc(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.update_group), "__call__") as call: - call.return_value = common.ErrorGroup() - client.update_group(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_group_service.UpdateGroupRequest() - - assert args[0] == request_msg - - -def test_transport_kind_grpc_asyncio(): - transport = ErrorGroupServiceAsyncClient.get_transport_class("grpc_asyncio")( - credentials=async_anonymous_credentials() - ) - assert transport.kind == "grpc_asyncio" - - -def test_initialize_client_w_grpc_asyncio(): - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), transport="grpc_asyncio" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_get_group_empty_call_grpc_asyncio(): - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - 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", - resolution_status=common.ResolutionStatus.OPEN, - ) - ) - await client.get_group(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_group_service.GetGroupRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_update_group_empty_call_grpc_asyncio(): - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - 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", - resolution_status=common.ResolutionStatus.OPEN, - ) - ) - await client.update_group(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_group_service.UpdateGroupRequest() - - assert args[0] == request_msg - - -def test_transport_kind_rest(): - transport = ErrorGroupServiceClient.get_transport_class("rest")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "rest" - - -def test_get_group_rest_bad_request(request_type=error_group_service.GetGroupRequest): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {"group_name": "projects/sample1/groups/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = mock.Mock() - json_return_value = "" - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_group(request) - - -@pytest.mark.parametrize( - "request_type", - [ - error_group_service.GetGroupRequest, - dict, - ], -) -def test_get_group_rest_call_success(request_type): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {"group_name": "projects/sample1/groups/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = common.ErrorGroup( - name="name_value", - group_id="group_id_value", - resolution_status=common.ResolutionStatus.OPEN, - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = common.ErrorGroup.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_group(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, common.ErrorGroup) - assert response.name == "name_value" - assert response.group_id == "group_id_value" - assert response.resolution_status == common.ResolutionStatus.OPEN - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_group_rest_interceptors(null_interceptor): - transport = transports.ErrorGroupServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ErrorGroupServiceRestInterceptor(), - ) - client = ErrorGroupServiceClient(transport=transport) - - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ErrorGroupServiceRestInterceptor, "post_get_group" - ) as post, mock.patch.object( - transports.ErrorGroupServiceRestInterceptor, "post_get_group_with_metadata" - ) as post_with_metadata, mock.patch.object( - transports.ErrorGroupServiceRestInterceptor, "pre_get_group" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - post_with_metadata.assert_not_called() - pb_message = error_group_service.GetGroupRequest.pb( - error_group_service.GetGroupRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = common.ErrorGroup.to_json(common.ErrorGroup()) - req.return_value.content = return_value - - request = error_group_service.GetGroupRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = common.ErrorGroup() - post_with_metadata.return_value = common.ErrorGroup(), metadata - - client.get_group( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - post_with_metadata.assert_called_once() - - -def test_update_group_rest_bad_request( - request_type=error_group_service.UpdateGroupRequest, -): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {"group": {"name": "projects/sample1/groups/sample2"}} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = mock.Mock() - json_return_value = "" - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.update_group(request) - - -@pytest.mark.parametrize( - "request_type", - [ - error_group_service.UpdateGroupRequest, - dict, - ], -) -def test_update_group_rest_call_success(request_type): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {"group": {"name": "projects/sample1/groups/sample2"}} - request_init["group"] = { - "name": "projects/sample1/groups/sample2", - "group_id": "group_id_value", - "tracking_issues": [{"url": "url_value"}], - "resolution_status": 1, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = error_group_service.UpdateGroupRequest.meta.fields["group"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["group"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["group"][field])): - del request_init["group"][field][i][subfield] - else: - del request_init["group"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = common.ErrorGroup( - name="name_value", - group_id="group_id_value", - resolution_status=common.ResolutionStatus.OPEN, - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = common.ErrorGroup.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.update_group(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, common.ErrorGroup) - assert response.name == "name_value" - assert response.group_id == "group_id_value" - assert response.resolution_status == common.ResolutionStatus.OPEN - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_group_rest_interceptors(null_interceptor): - transport = transports.ErrorGroupServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ErrorGroupServiceRestInterceptor(), - ) - client = ErrorGroupServiceClient(transport=transport) - - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ErrorGroupServiceRestInterceptor, "post_update_group" - ) as post, mock.patch.object( - transports.ErrorGroupServiceRestInterceptor, "post_update_group_with_metadata" - ) as post_with_metadata, mock.patch.object( - transports.ErrorGroupServiceRestInterceptor, "pre_update_group" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - post_with_metadata.assert_not_called() - pb_message = error_group_service.UpdateGroupRequest.pb( - error_group_service.UpdateGroupRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = common.ErrorGroup.to_json(common.ErrorGroup()) - req.return_value.content = return_value - - request = error_group_service.UpdateGroupRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = common.ErrorGroup() - post_with_metadata.return_value = common.ErrorGroup(), metadata - - client.update_group( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - post_with_metadata.assert_called_once() - - -def test_initialize_client_w_rest(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_get_group_empty_call_rest(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.get_group), "__call__") as call: - client.get_group(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_group_service.GetGroupRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_update_group_empty_call_rest(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.update_group), "__call__") as call: - client.update_group(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_group_service.UpdateGroupRequest() - - assert args[0] == request_msg - - -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert isinstance( - client.transport, - transports.ErrorGroupServiceGrpcTransport, - ) - - -def test_error_group_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.ErrorGroupServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json", - ) - - -def test_error_group_service_base_transport(): - # Instantiate the base transport. - with mock.patch( - "google.cloud.errorreporting_v1beta1.services.error_group_service.transports.ErrorGroupServiceTransport.__init__" - ) as Transport: - Transport.return_value = None - transport = transports.ErrorGroupServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - "get_group", - "update_group", - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - # Catch all for all remaining methods and properties - remainder = [ - "kind", - ] - for r in remainder: - with pytest.raises(NotImplementedError): - getattr(transport, r)() - - -def test_error_group_service_base_transport_with_credentials_file(): - # Instantiate the base transport with a credentials file - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch( - "google.cloud.errorreporting_v1beta1.services.error_group_service.transports.ErrorGroupServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ErrorGroupServiceTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with( - "credentials.json", - scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id="octopus", - ) - - -def test_error_group_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( - "google.cloud.errorreporting_v1beta1.services.error_group_service.transports.ErrorGroupServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ErrorGroupServiceTransport() - adc.assert_called_once() - - -def test_error_group_service_auth_adc(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - ErrorGroupServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ErrorGroupServiceGrpcTransport, - transports.ErrorGroupServiceGrpcAsyncIOTransport, - ], -) -def test_error_group_service_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ErrorGroupServiceGrpcTransport, - transports.ErrorGroupServiceGrpcAsyncIOTransport, - transports.ErrorGroupServiceRestTransport, - ], -) -def test_error_group_service_transport_auth_gdch_credentials(transport_class): - host = "https://language.com" - api_audience_tests = [None, "https://language2.com"] - api_audience_expect = [host, "https://language2.com"] - for t, e in zip(api_audience_tests, api_audience_expect): - with mock.patch.object(google.auth, "default", autospec=True) as adc: - gdch_mock = mock.MagicMock() - type(gdch_mock).with_gdch_audience = mock.PropertyMock( - return_value=gdch_mock - ) - adc.return_value = (gdch_mock, None) - transport_class(host=host, api_audience=t) - gdch_mock.with_gdch_audience.assert_called_once_with(e) - - -@pytest.mark.parametrize( - "transport_class,grpc_helpers", - [ - (transports.ErrorGroupServiceGrpcTransport, grpc_helpers), - (transports.ErrorGroupServiceGrpcAsyncIOTransport, grpc_helpers_async), - ], -) -def test_error_group_service_transport_create_channel(transport_class, grpc_helpers): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object( - google.auth, "default", autospec=True - ) as adc, mock.patch.object( - grpc_helpers, "create_channel", autospec=True - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - adc.return_value = (creds, None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - - create_channel.assert_called_with( - "clouderrorreporting.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - scopes=["1", "2"], - default_host="clouderrorreporting.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ErrorGroupServiceGrpcTransport, - transports.ErrorGroupServiceGrpcAsyncIOTransport, - ], -) -def test_error_group_service_grpc_transport_client_cert_source_for_mtls( - transport_class, -): - cred = ga_credentials.AnonymousCredentials() - - # Check ssl_channel_credentials is used if provided. - with mock.patch.object(transport_class, "create_channel") as mock_create_channel: - mock_ssl_channel_creds = mock.Mock() - transport_class( - host="squid.clam.whelk", - credentials=cred, - ssl_channel_credentials=mock_ssl_channel_creds, - ) - mock_create_channel.assert_called_once_with( - "squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_channel_creds, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls - # is used. - with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): - with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: - transport_class( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback, - ) - expected_cert, expected_key = client_cert_source_callback() - mock_ssl_cred.assert_called_once_with( - certificate_chain=expected_cert, private_key=expected_key - ) - - -def test_error_group_service_http_transport_client_cert_source_for_mtls(): - cred = ga_credentials.AnonymousCredentials() - with mock.patch( - "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" - ) as mock_configure_mtls_channel: - transports.ErrorGroupServiceRestTransport( - credentials=cred, client_cert_source_for_mtls=client_cert_source_callback - ) - mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) - - -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "grpc_asyncio", - "rest", - ], -) -def test_error_group_service_host_no_port(transport_name): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions( - api_endpoint="clouderrorreporting.googleapis.com" - ), - transport=transport_name, - ) - assert client.transport._host == ( - "clouderrorreporting.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://clouderrorreporting.googleapis.com" - ) - - -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "grpc_asyncio", - "rest", - ], -) -def test_error_group_service_host_with_port(transport_name): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions( - api_endpoint="clouderrorreporting.googleapis.com:8000" - ), - transport=transport_name, - ) - assert client.transport._host == ( - "clouderrorreporting.googleapis.com:8000" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://clouderrorreporting.googleapis.com:8000" - ) - - -@pytest.mark.parametrize( - "transport_name", - [ - "rest", - ], -) -def test_error_group_service_client_transport_session_collision(transport_name): - creds1 = ga_credentials.AnonymousCredentials() - creds2 = ga_credentials.AnonymousCredentials() - client1 = ErrorGroupServiceClient( - credentials=creds1, - transport=transport_name, - ) - client2 = ErrorGroupServiceClient( - credentials=creds2, - transport=transport_name, - ) - session1 = client1.transport.get_group._session - session2 = client2.transport.get_group._session - assert session1 != session2 - session1 = client1.transport.update_group._session - session2 = client2.transport.update_group._session - assert session1 != session2 - - -def test_error_group_service_grpc_transport_channel(): - channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.ErrorGroupServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -def test_error_group_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.ErrorGroupServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.filterwarnings("ignore::FutureWarning") -@pytest.mark.parametrize( - "transport_class", - [ - transports.ErrorGroupServiceGrpcTransport, - transports.ErrorGroupServiceGrpcAsyncIOTransport, - ], -) -def test_error_group_service_transport_channel_mtls_with_client_cert_source( - transport_class, -): - with mock.patch( - "grpc.ssl_channel_credentials", autospec=True - ) as grpc_ssl_channel_cred: - with mock.patch.object( - transport_class, "create_channel" - ) as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = ga_credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - assert transport._ssl_channel_credentials == mock_ssl_cred - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize( - "transport_class", - [ - transports.ErrorGroupServiceGrpcTransport, - transports.ErrorGroupServiceGrpcAsyncIOTransport, - ], -) -def test_error_group_service_transport_channel_mtls_with_adc(transport_class): - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - with mock.patch.object( - transport_class, "create_channel" - ) as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_error_group_path(): - project = "squid" - group = "clam" - expected = "projects/{project}/groups/{group}".format( - project=project, - group=group, - ) - actual = ErrorGroupServiceClient.error_group_path(project, group) - assert expected == actual - - -def test_parse_error_group_path(): - expected = { - "project": "whelk", - "group": "octopus", - } - path = ErrorGroupServiceClient.error_group_path(**expected) - - # Check that the path construction is reversible. - actual = ErrorGroupServiceClient.parse_error_group_path(path) - assert expected == actual - - -def test_common_billing_account_path(): - billing_account = "oyster" - expected = "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - actual = ErrorGroupServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "nudibranch", - } - path = ErrorGroupServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = ErrorGroupServiceClient.parse_common_billing_account_path(path) - assert expected == actual - - -def test_common_folder_path(): - folder = "cuttlefish" - expected = "folders/{folder}".format( - folder=folder, - ) - actual = ErrorGroupServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "mussel", - } - path = ErrorGroupServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = ErrorGroupServiceClient.parse_common_folder_path(path) - assert expected == actual - - -def test_common_organization_path(): - organization = "winkle" - expected = "organizations/{organization}".format( - organization=organization, - ) - actual = ErrorGroupServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "nautilus", - } - path = ErrorGroupServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = ErrorGroupServiceClient.parse_common_organization_path(path) - assert expected == actual - - -def test_common_project_path(): - project = "scallop" - expected = "projects/{project}".format( - project=project, - ) - actual = ErrorGroupServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "abalone", - } - path = ErrorGroupServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = ErrorGroupServiceClient.parse_common_project_path(path) - assert expected == actual - - -def test_common_location_path(): - project = "squid" - location = "clam" - expected = "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - actual = ErrorGroupServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "whelk", - "location": "octopus", - } - path = ErrorGroupServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = ErrorGroupServiceClient.parse_common_location_path(path) - assert expected == actual - - -def test_client_with_default_client_info(): - client_info = gapic_v1.client_info.ClientInfo() - - with mock.patch.object( - transports.ErrorGroupServiceTransport, "_prep_wrapped_messages" - ) as prep: - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object( - transports.ErrorGroupServiceTransport, "_prep_wrapped_messages" - ) as prep: - transport_class = ErrorGroupServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -def test_transport_close_grpc(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc" - ) - with mock.patch.object( - type(getattr(client.transport, "_grpc_channel")), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -@pytest.mark.asyncio -async def test_transport_close_grpc_asyncio(): - client = ErrorGroupServiceAsyncClient( - credentials=async_anonymous_credentials(), transport="grpc_asyncio" - ) - with mock.patch.object( - type(getattr(client.transport, "_grpc_channel")), "close" - ) as close: - async with client: - close.assert_not_called() - close.assert_called_once() - - -def test_transport_close_rest(): - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - with mock.patch.object( - type(getattr(client.transport, "_session")), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -def test_client_ctx(): - transports = [ - "rest", - "grpc", - ] - for transport in transports: - client = ErrorGroupServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - # Test client calls underlying transport. - with mock.patch.object(type(client.transport), "close") as close: - close.assert_not_called() - with client: - pass - close.assert_called() - - -@pytest.mark.parametrize( - "client_class,transport_class", - [ - (ErrorGroupServiceClient, transports.ErrorGroupServiceGrpcTransport), - ( - ErrorGroupServiceAsyncClient, - transports.ErrorGroupServiceGrpcAsyncIOTransport, - ), - ], -) -def test_api_key_credentials(client_class, transport_class): - with mock.patch.object( - google.auth._default, "get_api_key_credentials", create=True - ) as get_api_key_credentials: - mock_cred = mock.Mock() - get_api_key_credentials.return_value = mock_cred - options = client_options.ClientOptions() - options.api_key = "api_key" - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=mock_cred, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) diff --git a/tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py b/tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py deleted file mode 100644 index 386d0df3..00000000 --- a/tests/unit/gapic/errorreporting_v1beta1/test_error_stats_service.py +++ /dev/null @@ -1,4887 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import os - -# try/except added for compatibility with python < 3.8 -try: - from unittest import mock - from unittest.mock import AsyncMock # pragma: NO COVER -except ImportError: # pragma: NO COVER - import mock - -import grpc -from grpc.experimental import aio -from collections.abc import Iterable, AsyncIterable -from google.protobuf import json_format -import json -import math -import pytest -from collections.abc import Sequence, Mapping -from google.api_core import api_core_version -from proto.marshal.rules.dates import DurationRule, TimestampRule -from proto.marshal.rules import wrappers -from requests import Response -from requests import Request, PreparedRequest -from requests.sessions import Session -from google.protobuf import json_format - -try: - from google.auth.aio import credentials as ga_credentials_async - - HAS_GOOGLE_AUTH_AIO = True -except ImportError: # pragma: NO COVER - HAS_GOOGLE_AUTH_AIO = False - -from google.api_core import client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers -from google.api_core import grpc_helpers_async -from google.api_core import path_template -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.cloud.errorreporting_v1beta1.services.error_stats_service import ( - ErrorStatsServiceAsyncClient, -) -from google.cloud.errorreporting_v1beta1.services.error_stats_service import ( - ErrorStatsServiceClient, -) -from google.cloud.errorreporting_v1beta1.services.error_stats_service import pagers -from google.cloud.errorreporting_v1beta1.services.error_stats_service import transports -from google.cloud.errorreporting_v1beta1.types import common -from google.cloud.errorreporting_v1beta1.types import error_stats_service -from google.oauth2 import service_account -import google.auth -import google.protobuf.duration_pb2 as duration_pb2 # type: ignore -import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore - - -CRED_INFO_JSON = { - "credential_source": "/path/to/file", - "credential_type": "service account credentials", - "principal": "service-account@example.com", -} -CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) - - -async def mock_async_gen(data, chunk_size=1): - for i in range(0, len(data)): # pragma: NO COVER - chunk = data[i : i + chunk_size] - yield chunk.encode("utf-8") - - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - - -# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. -# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. -def async_anonymous_credentials(): - if HAS_GOOGLE_AUTH_AIO: - return ga_credentials_async.AnonymousCredentials() - return ga_credentials.AnonymousCredentials() - - -# If default endpoint is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint(client): - return ( - "foo.googleapis.com" - if ("localhost" in client.DEFAULT_ENDPOINT) - else client.DEFAULT_ENDPOINT - ) - - -# If default endpoint template is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint template so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint_template(client): - return ( - "test.{UNIVERSE_DOMAIN}" - if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) - else client._DEFAULT_ENDPOINT_TEMPLATE - ) - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert ErrorStatsServiceClient._get_default_mtls_endpoint(None) is None - assert ( - ErrorStatsServiceClient._get_default_mtls_endpoint(api_endpoint) - == api_mtls_endpoint - ) - assert ( - ErrorStatsServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) - == api_mtls_endpoint - ) - assert ( - ErrorStatsServiceClient._get_default_mtls_endpoint(sandbox_endpoint) - == sandbox_mtls_endpoint - ) - assert ( - ErrorStatsServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) - == sandbox_mtls_endpoint - ) - assert ( - ErrorStatsServiceClient._get_default_mtls_endpoint(non_googleapi) - == non_googleapi - ) - - -def test__read_environment_variables(): - assert ErrorStatsServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert ErrorStatsServiceClient._read_environment_variables() == ( - True, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - assert ErrorStatsServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with pytest.raises(ValueError) as excinfo: - ErrorStatsServiceClient._read_environment_variables() - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - else: - assert ErrorStatsServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - assert ErrorStatsServiceClient._read_environment_variables() == ( - False, - "never", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - assert ErrorStatsServiceClient._read_environment_variables() == ( - False, - "always", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): - assert ErrorStatsServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - ErrorStatsServiceClient._read_environment_variables() - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): - assert ErrorStatsServiceClient._read_environment_variables() == ( - False, - "auto", - "foo.com", - ) - - -def test_use_client_cert_effective(): - # Test case 1: Test when `should_use_client_cert` returns True. - # We mock the `should_use_client_cert` function to simulate a scenario where - # the google-auth library supports automatic mTLS and determines that a - # client certificate should be used. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch( - "google.auth.transport.mtls.should_use_client_cert", return_value=True - ): - assert ErrorStatsServiceClient._use_client_cert_effective() is True - - # Test case 2: Test when `should_use_client_cert` returns False. - # We mock the `should_use_client_cert` function to simulate a scenario where - # the google-auth library supports automatic mTLS and determines that a - # client certificate should NOT be used. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch( - "google.auth.transport.mtls.should_use_client_cert", return_value=False - ): - assert ErrorStatsServiceClient._use_client_cert_effective() is False - - # Test case 3: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert ErrorStatsServiceClient._use_client_cert_effective() is True - - # Test case 4: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} - ): - assert ErrorStatsServiceClient._use_client_cert_effective() is False - - # Test case 5: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): - assert ErrorStatsServiceClient._use_client_cert_effective() is True - - # Test case 6: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} - ): - assert ErrorStatsServiceClient._use_client_cert_effective() is False - - # Test case 7: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): - assert ErrorStatsServiceClient._use_client_cert_effective() is True - - # Test case 8: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} - ): - assert ErrorStatsServiceClient._use_client_cert_effective() is False - - # Test case 9: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set. - # In this case, the method should return False, which is the default value. - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, clear=True): - assert ErrorStatsServiceClient._use_client_cert_effective() is False - - # Test case 10: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. - # The method should raise a ValueError as the environment variable must be either - # "true" or "false". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} - ): - with pytest.raises(ValueError): - ErrorStatsServiceClient._use_client_cert_effective() - - # Test case 11: Test when `should_use_client_cert` is available and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. - # The method should return False as the environment variable is set to an invalid value. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} - ): - assert ErrorStatsServiceClient._use_client_cert_effective() is False - - # Test case 12: Test when `should_use_client_cert` is available and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also, - # the GOOGLE_API_CONFIG environment variable is unset. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}): - with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}): - assert ErrorStatsServiceClient._use_client_cert_effective() is False - - -def test__get_client_cert_source(): - mock_provided_cert_source = mock.Mock() - mock_default_cert_source = mock.Mock() - - assert ErrorStatsServiceClient._get_client_cert_source(None, False) is None - assert ( - ErrorStatsServiceClient._get_client_cert_source( - mock_provided_cert_source, False - ) - is None - ) - assert ( - ErrorStatsServiceClient._get_client_cert_source(mock_provided_cert_source, True) - == mock_provided_cert_source - ) - - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", return_value=True - ): - with mock.patch( - "google.auth.transport.mtls.default_client_cert_source", - return_value=mock_default_cert_source, - ): - assert ( - ErrorStatsServiceClient._get_client_cert_source(None, True) - is mock_default_cert_source - ) - assert ( - ErrorStatsServiceClient._get_client_cert_source( - mock_provided_cert_source, "true" - ) - is mock_provided_cert_source - ) - - -@mock.patch.object( - ErrorStatsServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorStatsServiceClient), -) -@mock.patch.object( - ErrorStatsServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorStatsServiceAsyncClient), -) -def test__get_api_endpoint(): - api_override = "foo.com" - mock_client_cert_source = mock.Mock() - default_universe = ErrorStatsServiceClient._DEFAULT_UNIVERSE - default_endpoint = ErrorStatsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=default_universe - ) - mock_universe = "bar.com" - mock_endpoint = ErrorStatsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=mock_universe - ) - - assert ( - ErrorStatsServiceClient._get_api_endpoint( - api_override, mock_client_cert_source, default_universe, "always" - ) - == api_override - ) - assert ( - ErrorStatsServiceClient._get_api_endpoint( - None, mock_client_cert_source, default_universe, "auto" - ) - == ErrorStatsServiceClient.DEFAULT_MTLS_ENDPOINT - ) - assert ( - ErrorStatsServiceClient._get_api_endpoint(None, None, default_universe, "auto") - == default_endpoint - ) - assert ( - ErrorStatsServiceClient._get_api_endpoint( - None, None, default_universe, "always" - ) - == ErrorStatsServiceClient.DEFAULT_MTLS_ENDPOINT - ) - assert ( - ErrorStatsServiceClient._get_api_endpoint( - None, mock_client_cert_source, default_universe, "always" - ) - == ErrorStatsServiceClient.DEFAULT_MTLS_ENDPOINT - ) - assert ( - ErrorStatsServiceClient._get_api_endpoint(None, None, mock_universe, "never") - == mock_endpoint - ) - assert ( - ErrorStatsServiceClient._get_api_endpoint(None, None, default_universe, "never") - == default_endpoint - ) - - with pytest.raises(MutualTLSChannelError) as excinfo: - ErrorStatsServiceClient._get_api_endpoint( - None, mock_client_cert_source, mock_universe, "auto" - ) - assert ( - str(excinfo.value) - == "mTLS is not supported in any universe other than googleapis.com." - ) - - -def test__get_universe_domain(): - client_universe_domain = "foo.com" - universe_domain_env = "bar.com" - - assert ( - ErrorStatsServiceClient._get_universe_domain( - client_universe_domain, universe_domain_env - ) - == client_universe_domain - ) - assert ( - ErrorStatsServiceClient._get_universe_domain(None, universe_domain_env) - == universe_domain_env - ) - assert ( - ErrorStatsServiceClient._get_universe_domain(None, None) - == ErrorStatsServiceClient._DEFAULT_UNIVERSE - ) - - with pytest.raises(ValueError) as excinfo: - ErrorStatsServiceClient._get_universe_domain("", None) - assert str(excinfo.value) == "Universe Domain cannot be an empty string." - - -@pytest.mark.parametrize( - "error_code,cred_info_json,show_cred_info", - [ - (401, CRED_INFO_JSON, True), - (403, CRED_INFO_JSON, True), - (404, CRED_INFO_JSON, True), - (500, CRED_INFO_JSON, False), - (401, None, False), - (403, None, False), - (404, None, False), - (500, None, False), - ], -) -def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): - cred = mock.Mock(["get_cred_info"]) - cred.get_cred_info = mock.Mock(return_value=cred_info_json) - client = ErrorStatsServiceClient(credentials=cred) - client._transport._credentials = cred - - error = core_exceptions.GoogleAPICallError("message", details=["foo"]) - error.code = error_code - - client._add_cred_info_for_auth_errors(error) - if show_cred_info: - assert error.details == ["foo", CRED_INFO_STRING] - else: - assert error.details == ["foo"] - - -@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) -def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): - cred = mock.Mock([]) - assert not hasattr(cred, "get_cred_info") - client = ErrorStatsServiceClient(credentials=cred) - client._transport._credentials = cred - - error = core_exceptions.GoogleAPICallError("message", details=[]) - error.code = error_code - - client._add_cred_info_for_auth_errors(error) - assert error.details == [] - - -@pytest.mark.parametrize( - "client_class,transport_name", - [ - (ErrorStatsServiceClient, "grpc"), - (ErrorStatsServiceAsyncClient, "grpc_asyncio"), - (ErrorStatsServiceClient, "rest"), - ], -) -def test_error_stats_service_client_from_service_account_info( - client_class, transport_name -): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object( - service_account.Credentials, "from_service_account_info" - ) as factory: - factory.return_value = creds - info = {"valid": True} - client = client_class.from_service_account_info(info, transport=transport_name) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == ( - "clouderrorreporting.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://clouderrorreporting.googleapis.com" - ) - - -@pytest.mark.parametrize( - "transport_class,transport_name", - [ - (transports.ErrorStatsServiceGrpcTransport, "grpc"), - (transports.ErrorStatsServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (transports.ErrorStatsServiceRestTransport, "rest"), - ], -) -def test_error_stats_service_client_service_account_always_use_jwt( - transport_class, transport_name -): - with mock.patch.object( - service_account.Credentials, "with_always_use_jwt_access", create=True - ) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=True) - use_jwt.assert_called_once_with(True) - - with mock.patch.object( - service_account.Credentials, "with_always_use_jwt_access", create=True - ) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=False) - use_jwt.assert_not_called() - - -@pytest.mark.parametrize( - "client_class,transport_name", - [ - (ErrorStatsServiceClient, "grpc"), - (ErrorStatsServiceAsyncClient, "grpc_asyncio"), - (ErrorStatsServiceClient, "rest"), - ], -) -def test_error_stats_service_client_from_service_account_file( - client_class, transport_name -): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object( - service_account.Credentials, "from_service_account_file" - ) as factory: - factory.return_value = creds - client = client_class.from_service_account_file( - "dummy/file/path.json", transport=transport_name - ) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - client = client_class.from_service_account_json( - "dummy/file/path.json", transport=transport_name - ) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == ( - "clouderrorreporting.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://clouderrorreporting.googleapis.com" - ) - - -def test_error_stats_service_client_get_transport_class(): - transport = ErrorStatsServiceClient.get_transport_class() - available_transports = [ - transports.ErrorStatsServiceGrpcTransport, - transports.ErrorStatsServiceRestTransport, - ] - assert transport in available_transports - - transport = ErrorStatsServiceClient.get_transport_class("grpc") - assert transport == transports.ErrorStatsServiceGrpcTransport - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name", - [ - (ErrorStatsServiceClient, transports.ErrorStatsServiceGrpcTransport, "grpc"), - ( - ErrorStatsServiceAsyncClient, - transports.ErrorStatsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - ), - (ErrorStatsServiceClient, transports.ErrorStatsServiceRestTransport, "rest"), - ], -) -@mock.patch.object( - ErrorStatsServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorStatsServiceClient), -) -@mock.patch.object( - ErrorStatsServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorStatsServiceAsyncClient), -) -def test_error_stats_service_client_client_options( - client_class, transport_class, transport_name -): - # Check that if channel is provided we won't create a new one. - with mock.patch.object(ErrorStatsServiceClient, "get_transport_class") as gtc: - transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) - client = client_class(transport=transport) - gtc.assert_not_called() - - # Check that if channel is provided via str we will create a new one. - with mock.patch.object(ErrorStatsServiceClient, "get_transport_class") as gtc: - client = client_class(transport=transport_name) - gtc.assert_called() - - # Check the case api_endpoint is provided. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - client = client_class(transport=transport_name) - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - # Check the case api_endpoint is provided - options = client_options.ClientOptions( - api_audience="https://language.googleapis.com" - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience="https://language.googleapis.com", - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,use_client_cert_env", - [ - ( - ErrorStatsServiceClient, - transports.ErrorStatsServiceGrpcTransport, - "grpc", - "true", - ), - ( - ErrorStatsServiceAsyncClient, - transports.ErrorStatsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "true", - ), - ( - ErrorStatsServiceClient, - transports.ErrorStatsServiceGrpcTransport, - "grpc", - "false", - ), - ( - ErrorStatsServiceAsyncClient, - transports.ErrorStatsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "false", - ), - ( - ErrorStatsServiceClient, - transports.ErrorStatsServiceRestTransport, - "rest", - "true", - ), - ( - ErrorStatsServiceClient, - transports.ErrorStatsServiceRestTransport, - "rest", - "false", - ), - ], -) -@mock.patch.object( - ErrorStatsServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorStatsServiceClient), -) -@mock.patch.object( - ErrorStatsServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorStatsServiceAsyncClient), -) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_error_stats_service_client_mtls_env_auto( - client_class, transport_class, transport_name, use_client_cert_env -): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - options = client_options.ClientOptions( - client_cert_source=client_cert_source_callback - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - - if use_client_cert_env == "false": - expected_client_cert_source = None - expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ) - else: - expected_client_cert_source = client_cert_source_callback - expected_host = client.DEFAULT_MTLS_ENDPOINT - - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, - ): - with mock.patch( - "google.auth.transport.mtls.default_client_cert_source", - return_value=client_cert_source_callback, - ): - if use_client_cert_env == "false": - expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ) - expected_client_cert_source = None - else: - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_client_cert_source = client_cert_source_callback - - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, - ): - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize( - "client_class", [ErrorStatsServiceClient, ErrorStatsServiceAsyncClient] -) -@mock.patch.object( - ErrorStatsServiceClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(ErrorStatsServiceClient), -) -@mock.patch.object( - ErrorStatsServiceAsyncClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(ErrorStatsServiceAsyncClient), -) -def test_error_stats_service_client_get_mtls_endpoint_and_cert_source(client_class): - mock_client_cert_source = mock.Mock() - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint - ) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( - options - ) - assert api_endpoint == mock_api_endpoint - assert cert_source == mock_client_cert_source - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint - ) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( - options - ) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "Unsupported". - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, - api_endpoint=mock_api_endpoint, - ) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( - options - ) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset. - test_cases = [ - ( - # With workloads present in config, mTLS is enabled. - { - "version": 1, - "cert_configs": { - "workload": { - "cert_path": "path/to/cert/file", - "key_path": "path/to/key/file", - } - }, - }, - mock_client_cert_source, - ), - ( - # With workloads not present in config, mTLS is disabled. - { - "version": 1, - "cert_configs": {}, - }, - None, - ), - ] - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - for config_data, expected_cert_source in test_cases: - env = os.environ.copy() - env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) - with mock.patch.dict(os.environ, env, clear=True): - config_filename = "mock_certificate_config.json" - config_file_content = json.dumps(config_data) - m = mock.mock_open(read_data=config_file_content) - with mock.patch("builtins.open", m): - with mock.patch.dict( - os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} - ): - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, - api_endpoint=mock_api_endpoint, - ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is expected_cert_source - - # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). - test_cases = [ - ( - # With workloads present in config, mTLS is enabled. - { - "version": 1, - "cert_configs": { - "workload": { - "cert_path": "path/to/cert/file", - "key_path": "path/to/key/file", - } - }, - }, - mock_client_cert_source, - ), - ( - # With workloads not present in config, mTLS is disabled. - { - "version": 1, - "cert_configs": {}, - }, - None, - ), - ] - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - for config_data, expected_cert_source in test_cases: - env = os.environ.copy() - env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") - with mock.patch.dict(os.environ, env, clear=True): - config_filename = "mock_certificate_config.json" - config_file_content = json.dumps(config_data) - m = mock.mock_open(read_data=config_file_content) - with mock.patch("builtins.open", m): - with mock.patch.dict( - os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} - ): - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, - api_endpoint=mock_api_endpoint, - ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is expected_cert_source - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, - ): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, - ): - with mock.patch( - "google.auth.transport.mtls.default_client_cert_source", - return_value=mock_client_cert_source, - ): - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source == mock_client_cert_source - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - -@pytest.mark.parametrize( - "client_class", [ErrorStatsServiceClient, ErrorStatsServiceAsyncClient] -) -@mock.patch.object( - ErrorStatsServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorStatsServiceClient), -) -@mock.patch.object( - ErrorStatsServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ErrorStatsServiceAsyncClient), -) -def test_error_stats_service_client_client_api_endpoint(client_class): - mock_client_cert_source = client_cert_source_callback - api_override = "foo.com" - default_universe = ErrorStatsServiceClient._DEFAULT_UNIVERSE - default_endpoint = ErrorStatsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=default_universe - ) - mock_universe = "bar.com" - mock_endpoint = ErrorStatsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=mock_universe - ) - - # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", - # use ClientOptions.api_endpoint as the api endpoint regardless. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch( - "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" - ): - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, api_endpoint=api_override - ) - client = client_class( - client_options=options, - credentials=ga_credentials.AnonymousCredentials(), - ) - assert client.api_endpoint == api_override - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", - # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - - # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), - # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, - # and ClientOptions.universe_domain="bar.com", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. - options = client_options.ClientOptions() - universe_exists = hasattr(options, "universe_domain") - if universe_exists: - options = client_options.ClientOptions(universe_domain=mock_universe) - client = client_class( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - else: - client = client_class( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - assert client.api_endpoint == ( - mock_endpoint if universe_exists else default_endpoint - ) - assert client.universe_domain == ( - mock_universe if universe_exists else default_universe - ) - - # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - options = client_options.ClientOptions() - if hasattr(options, "universe_domain"): - delattr(options, "universe_domain") - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - assert client.api_endpoint == default_endpoint - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name", - [ - (ErrorStatsServiceClient, transports.ErrorStatsServiceGrpcTransport, "grpc"), - ( - ErrorStatsServiceAsyncClient, - transports.ErrorStatsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - ), - (ErrorStatsServiceClient, transports.ErrorStatsServiceRestTransport, "rest"), - ], -) -def test_error_stats_service_client_client_options_scopes( - client_class, transport_class, transport_name -): - # Check the case scopes are provided. - options = client_options.ClientOptions( - scopes=["1", "2"], - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=["1", "2"], - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,grpc_helpers", - [ - ( - ErrorStatsServiceClient, - transports.ErrorStatsServiceGrpcTransport, - "grpc", - grpc_helpers, - ), - ( - ErrorStatsServiceAsyncClient, - transports.ErrorStatsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - grpc_helpers_async, - ), - ( - ErrorStatsServiceClient, - transports.ErrorStatsServiceRestTransport, - "rest", - None, - ), - ], -) -def test_error_stats_service_client_client_options_credentials_file( - client_class, transport_class, transport_name, grpc_helpers -): - # Check the case credentials file is provided. - options = client_options.ClientOptions(credentials_file="credentials.json") - - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -def test_error_stats_service_client_client_options_from_dict(): - with mock.patch( - "google.cloud.errorreporting_v1beta1.services.error_stats_service.transports.ErrorStatsServiceGrpcTransport.__init__" - ) as grpc_transport: - grpc_transport.return_value = None - client = ErrorStatsServiceClient( - client_options={"api_endpoint": "squid.clam.whelk"} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,grpc_helpers", - [ - ( - ErrorStatsServiceClient, - transports.ErrorStatsServiceGrpcTransport, - "grpc", - grpc_helpers, - ), - ( - ErrorStatsServiceAsyncClient, - transports.ErrorStatsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - grpc_helpers_async, - ), - ], -) -def test_error_stats_service_client_create_channel_credentials_file( - client_class, transport_class, transport_name, grpc_helpers -): - # Check the case credentials file is provided. - options = client_options.ClientOptions(credentials_file="credentials.json") - - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # test that the credentials from file are saved and used as the credentials. - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch.object( - google.auth, "default", autospec=True - ) as adc, mock.patch.object( - grpc_helpers, "create_channel" - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - file_creds = ga_credentials.AnonymousCredentials() - load_creds.return_value = (file_creds, None) - adc.return_value = (creds, None) - client = client_class(client_options=options, transport=transport_name) - create_channel.assert_called_with( - "clouderrorreporting.googleapis.com:443", - credentials=file_creds, - credentials_file=None, - quota_project_id=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - scopes=None, - default_host="clouderrorreporting.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize( - "request_type", - [ - error_stats_service.ListGroupStatsRequest, - dict, - ], -) -def test_list_group_stats(request_type, transport: str = "grpc"): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_group_stats), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = error_stats_service.ListGroupStatsResponse( - next_page_token="next_page_token_value", - ) - response = client.list_group_stats(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = error_stats_service.ListGroupStatsRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListGroupStatsPager) - assert response.next_page_token == "next_page_token_value" - - -def test_list_group_stats_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = error_stats_service.ListGroupStatsRequest( - project_name="project_name_value", - page_token="page_token_value", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_group_stats), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_group_stats(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == error_stats_service.ListGroupStatsRequest( - project_name="project_name_value", - page_token="page_token_value", - ) - - -def test_list_group_stats_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_group_stats in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.list_group_stats - ] = mock_rpc - request = {} - client.list_group_stats(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_group_stats(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -@pytest.mark.asyncio -async def test_list_group_stats_async_use_cached_wrapped_rpc( - transport: str = "grpc_asyncio", -): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._client._transport.list_group_stats - in client._client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[ - client._client._transport.list_group_stats - ] = mock_rpc - - request = {} - await client.list_group_stats(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.list_group_stats(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -@pytest.mark.asyncio -async def test_list_group_stats_async( - transport: str = "grpc_asyncio", - request_type=error_stats_service.ListGroupStatsRequest, -): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_group_stats), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - error_stats_service.ListGroupStatsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_group_stats(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = error_stats_service.ListGroupStatsRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListGroupStatsAsyncPager) - assert response.next_page_token == "next_page_token_value" - - -@pytest.mark.asyncio -async def test_list_group_stats_async_from_dict(): - await test_list_group_stats_async(request_type=dict) - - -def test_list_group_stats_field_headers(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = error_stats_service.ListGroupStatsRequest() - - request.project_name = "project_name_value" - - # 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: - call.return_value = error_stats_service.ListGroupStatsResponse() - client.list_group_stats(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "project_name=project_name_value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_list_group_stats_field_headers_async(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = error_stats_service.ListGroupStatsRequest() - - request.project_name = "project_name_value" - - # 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: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - error_stats_service.ListGroupStatsResponse() - ) - await client.list_group_stats(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "project_name=project_name_value", - ) in kw["metadata"] - - -def test_list_group_stats_flattened(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # 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: - # Designate an appropriate return value for the call. - call.return_value = error_stats_service.ListGroupStatsResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.list_group_stats( - project_name="project_name_value", - time_range=error_stats_service.QueryTimeRange( - period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR - ), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].project_name - mock_val = "project_name_value" - assert arg == mock_val - arg = args[0].time_range - mock_val = error_stats_service.QueryTimeRange( - period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR - ) - assert arg == mock_val - - -def test_list_group_stats_flattened_error(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_group_stats( - error_stats_service.ListGroupStatsRequest(), - project_name="project_name_value", - time_range=error_stats_service.QueryTimeRange( - period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR - ), - ) - - -@pytest.mark.asyncio -async def test_list_group_stats_flattened_async(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # 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: - # Designate an appropriate return value for the call. - call.return_value = error_stats_service.ListGroupStatsResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - error_stats_service.ListGroupStatsResponse() - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.list_group_stats( - project_name="project_name_value", - time_range=error_stats_service.QueryTimeRange( - period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR - ), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].project_name - mock_val = "project_name_value" - assert arg == mock_val - arg = args[0].time_range - mock_val = error_stats_service.QueryTimeRange( - period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR - ) - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_list_group_stats_flattened_error_async(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.list_group_stats( - error_stats_service.ListGroupStatsRequest(), - project_name="project_name_value", - time_range=error_stats_service.QueryTimeRange( - period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR - ), - ) - - -def test_list_group_stats_pager(transport_name: str = "grpc"): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_group_stats), "__call__") as call: - # Set the response to a series of pages. - call.side_effect = ( - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - ], - next_page_token="abc", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[], - next_page_token="def", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - ], - next_page_token="ghi", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - ], - ), - RuntimeError, - ) - - expected_metadata = () - retry = retries.Retry() - timeout = 5 - expected_metadata = tuple(expected_metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("project_name", ""),)), - ) - pager = client.list_group_stats(request={}, retry=retry, timeout=timeout) - - assert pager._metadata == expected_metadata - assert pager._retry == retry - assert pager._timeout == timeout - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, error_stats_service.ErrorGroupStats) for i in results) - - -def test_list_group_stats_pages(transport_name: str = "grpc"): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_group_stats), "__call__") as call: - # Set the response to a series of pages. - call.side_effect = ( - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - ], - next_page_token="abc", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[], - next_page_token="def", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - ], - next_page_token="ghi", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - ], - ), - RuntimeError, - ) - pages = list(client.list_group_stats(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -@pytest.mark.asyncio -async def test_list_group_stats_async_pager(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_group_stats), "__call__", new_callable=mock.AsyncMock - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - ], - next_page_token="abc", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[], - next_page_token="def", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - ], - next_page_token="ghi", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - ], - ), - RuntimeError, - ) - async_pager = await client.list_group_stats( - request={}, - ) - assert async_pager.next_page_token == "abc" - responses = [] - async for response in async_pager: # pragma: no branch - responses.append(response) - - assert len(responses) == 6 - assert all( - isinstance(i, error_stats_service.ErrorGroupStats) for i in responses - ) - - -@pytest.mark.asyncio -async def test_list_group_stats_async_pages(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_group_stats), "__call__", new_callable=mock.AsyncMock - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - ], - next_page_token="abc", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[], - next_page_token="def", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - ], - next_page_token="ghi", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - ], - ), - RuntimeError, - ) - pages = [] - # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` - # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 - async for page_ in ( # pragma: no branch - await client.list_group_stats(request={}) - ).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -@pytest.mark.parametrize( - "request_type", - [ - error_stats_service.ListEventsRequest, - dict, - ], -) -def test_list_events(request_type, transport: str = "grpc"): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_events), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = error_stats_service.ListEventsResponse( - next_page_token="next_page_token_value", - ) - response = client.list_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = error_stats_service.ListEventsRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListEventsPager) - assert response.next_page_token == "next_page_token_value" - - -def test_list_events_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = error_stats_service.ListEventsRequest( - project_name="project_name_value", - group_id="group_id_value", - page_token="page_token_value", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_events), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.list_events(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == error_stats_service.ListEventsRequest( - project_name="project_name_value", - group_id="group_id_value", - page_token="page_token_value", - ) - - -def test_list_events_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_events in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.list_events] = mock_rpc - request = {} - client.list_events(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_events(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -@pytest.mark.asyncio -async def test_list_events_async_use_cached_wrapped_rpc( - transport: str = "grpc_asyncio", -): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._client._transport.list_events - in client._client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[ - client._client._transport.list_events - ] = mock_rpc - - request = {} - await client.list_events(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.list_events(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -@pytest.mark.asyncio -async def test_list_events_async( - transport: str = "grpc_asyncio", request_type=error_stats_service.ListEventsRequest -): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_events), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - error_stats_service.ListEventsResponse( - next_page_token="next_page_token_value", - ) - ) - response = await client.list_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = error_stats_service.ListEventsRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListEventsAsyncPager) - assert response.next_page_token == "next_page_token_value" - - -@pytest.mark.asyncio -async def test_list_events_async_from_dict(): - await test_list_events_async(request_type=dict) - - -def test_list_events_field_headers(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = error_stats_service.ListEventsRequest() - - request.project_name = "project_name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_events), "__call__") as call: - call.return_value = error_stats_service.ListEventsResponse() - client.list_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "project_name=project_name_value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_list_events_field_headers_async(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = error_stats_service.ListEventsRequest() - - request.project_name = "project_name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_events), "__call__") as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - error_stats_service.ListEventsResponse() - ) - await client.list_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "project_name=project_name_value", - ) in kw["metadata"] - - -def test_list_events_flattened(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_events), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = error_stats_service.ListEventsResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.list_events( - project_name="project_name_value", - group_id="group_id_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].project_name - mock_val = "project_name_value" - assert arg == mock_val - arg = args[0].group_id - mock_val = "group_id_value" - assert arg == mock_val - - -def test_list_events_flattened_error(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_events( - error_stats_service.ListEventsRequest(), - project_name="project_name_value", - group_id="group_id_value", - ) - - -@pytest.mark.asyncio -async def test_list_events_flattened_async(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_events), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = error_stats_service.ListEventsResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - error_stats_service.ListEventsResponse() - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.list_events( - project_name="project_name_value", - group_id="group_id_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].project_name - mock_val = "project_name_value" - assert arg == mock_val - arg = args[0].group_id - mock_val = "group_id_value" - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_list_events_flattened_error_async(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.list_events( - error_stats_service.ListEventsRequest(), - project_name="project_name_value", - group_id="group_id_value", - ) - - -def test_list_events_pager(transport_name: str = "grpc"): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_events), "__call__") as call: - # Set the response to a series of pages. - call.side_effect = ( - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - common.ErrorEvent(), - common.ErrorEvent(), - ], - next_page_token="abc", - ), - error_stats_service.ListEventsResponse( - error_events=[], - next_page_token="def", - ), - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - ], - next_page_token="ghi", - ), - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - common.ErrorEvent(), - ], - ), - RuntimeError, - ) - - expected_metadata = () - retry = retries.Retry() - timeout = 5 - expected_metadata = tuple(expected_metadata) + ( - gapic_v1.routing_header.to_grpc_metadata((("project_name", ""),)), - ) - pager = client.list_events(request={}, retry=retry, timeout=timeout) - - assert pager._metadata == expected_metadata - assert pager._retry == retry - assert pager._timeout == timeout - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, common.ErrorEvent) for i in results) - - -def test_list_events_pages(transport_name: str = "grpc"): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.list_events), "__call__") as call: - # Set the response to a series of pages. - call.side_effect = ( - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - common.ErrorEvent(), - common.ErrorEvent(), - ], - next_page_token="abc", - ), - error_stats_service.ListEventsResponse( - error_events=[], - next_page_token="def", - ), - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - ], - next_page_token="ghi", - ), - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - common.ErrorEvent(), - ], - ), - RuntimeError, - ) - pages = list(client.list_events(request={}).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -@pytest.mark.asyncio -async def test_list_events_async_pager(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_events), "__call__", new_callable=mock.AsyncMock - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - common.ErrorEvent(), - common.ErrorEvent(), - ], - next_page_token="abc", - ), - error_stats_service.ListEventsResponse( - error_events=[], - next_page_token="def", - ), - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - ], - next_page_token="ghi", - ), - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - common.ErrorEvent(), - ], - ), - RuntimeError, - ) - async_pager = await client.list_events( - request={}, - ) - assert async_pager.next_page_token == "abc" - responses = [] - async for response in async_pager: # pragma: no branch - responses.append(response) - - assert len(responses) == 6 - assert all(isinstance(i, common.ErrorEvent) for i in responses) - - -@pytest.mark.asyncio -async def test_list_events_async_pages(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_events), "__call__", new_callable=mock.AsyncMock - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - common.ErrorEvent(), - common.ErrorEvent(), - ], - next_page_token="abc", - ), - error_stats_service.ListEventsResponse( - error_events=[], - next_page_token="def", - ), - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - ], - next_page_token="ghi", - ), - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - common.ErrorEvent(), - ], - ), - RuntimeError, - ) - pages = [] - # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` - # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 - async for page_ in ( # pragma: no branch - await client.list_events(request={}) - ).pages: - pages.append(page_) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -@pytest.mark.parametrize( - "request_type", - [ - error_stats_service.DeleteEventsRequest, - dict, - ], -) -def test_delete_events(request_type, transport: str = "grpc"): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_events), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = error_stats_service.DeleteEventsResponse() - response = client.delete_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = error_stats_service.DeleteEventsRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, error_stats_service.DeleteEventsResponse) - - -def test_delete_events_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = error_stats_service.DeleteEventsRequest( - project_name="project_name_value", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_events), "__call__") as call: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.delete_events(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == error_stats_service.DeleteEventsRequest( - project_name="project_name_value", - ) - - -def test_delete_events_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.delete_events in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.delete_events] = mock_rpc - request = {} - client.delete_events(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.delete_events(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -@pytest.mark.asyncio -async def test_delete_events_async_use_cached_wrapped_rpc( - transport: str = "grpc_asyncio", -): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._client._transport.delete_events - in client._client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[ - client._client._transport.delete_events - ] = mock_rpc - - request = {} - await client.delete_events(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.delete_events(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -@pytest.mark.asyncio -async def test_delete_events_async( - transport: str = "grpc_asyncio", - request_type=error_stats_service.DeleteEventsRequest, -): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_events), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - error_stats_service.DeleteEventsResponse() - ) - response = await client.delete_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = error_stats_service.DeleteEventsRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, error_stats_service.DeleteEventsResponse) - - -@pytest.mark.asyncio -async def test_delete_events_async_from_dict(): - await test_delete_events_async(request_type=dict) - - -def test_delete_events_field_headers(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = error_stats_service.DeleteEventsRequest() - - request.project_name = "project_name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_events), "__call__") as call: - call.return_value = error_stats_service.DeleteEventsResponse() - client.delete_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "project_name=project_name_value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_delete_events_field_headers_async(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = error_stats_service.DeleteEventsRequest() - - request.project_name = "project_name_value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_events), "__call__") as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - error_stats_service.DeleteEventsResponse() - ) - await client.delete_events(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "project_name=project_name_value", - ) in kw["metadata"] - - -def test_delete_events_flattened(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_events), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = error_stats_service.DeleteEventsResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.delete_events( - project_name="project_name_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].project_name - mock_val = "project_name_value" - assert arg == mock_val - - -def test_delete_events_flattened_error(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_events( - error_stats_service.DeleteEventsRequest(), - project_name="project_name_value", - ) - - -@pytest.mark.asyncio -async def test_delete_events_flattened_async(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.delete_events), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = error_stats_service.DeleteEventsResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - error_stats_service.DeleteEventsResponse() - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.delete_events( - project_name="project_name_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].project_name - mock_val = "project_name_value" - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_delete_events_flattened_error_async(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.delete_events( - error_stats_service.DeleteEventsRequest(), - project_name="project_name_value", - ) - - -def test_list_group_stats_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_group_stats in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.list_group_stats - ] = mock_rpc - - request = {} - client.list_group_stats(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_group_stats(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_list_group_stats_rest_required_fields( - request_type=error_stats_service.ListGroupStatsRequest, -): - transport_class = transports.ErrorStatsServiceRestTransport - - request_init = {} - request_init["project_name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_group_stats._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["projectName"] = "project_name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_group_stats._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "alignment", - "alignment_time", - "group_id", - "order", - "page_size", - "page_token", - "service_filter", - "time_range", - "timed_count_duration", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "projectName" in jsonified_request - assert jsonified_request["projectName"] == "project_name_value" - - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = error_stats_service.ListGroupStatsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = error_stats_service.ListGroupStatsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - response = client.list_group_stats(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_list_group_stats_rest_unset_required_fields(): - transport = transports.ErrorStatsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.list_group_stats._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "alignment", - "alignmentTime", - "groupId", - "order", - "pageSize", - "pageToken", - "serviceFilter", - "timeRange", - "timedCountDuration", - ) - ) - & set(("projectName",)) - ) - - -def test_list_group_stats_rest_flattened(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = error_stats_service.ListGroupStatsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"project_name": "projects/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - project_name="project_name_value", - time_range=error_stats_service.QueryTimeRange( - period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR - ), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = error_stats_service.ListGroupStatsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.list_group_stats(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1beta1/{project_name=projects/*}/groupStats" % client.transport._host, - args[1], - ) - - -def test_list_group_stats_rest_flattened_error(transport: str = "rest"): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_group_stats( - error_stats_service.ListGroupStatsRequest(), - project_name="project_name_value", - time_range=error_stats_service.QueryTimeRange( - period=error_stats_service.QueryTimeRange.Period.PERIOD_1_HOUR - ), - ) - - -def test_list_group_stats_rest_pager(transport: str = "rest"): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - ], - next_page_token="abc", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[], - next_page_token="def", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - ], - next_page_token="ghi", - ), - error_stats_service.ListGroupStatsResponse( - error_group_stats=[ - error_stats_service.ErrorGroupStats(), - error_stats_service.ErrorGroupStats(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - error_stats_service.ListGroupStatsResponse.to_json(x) for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"project_name": "projects/sample1"} - - pager = client.list_group_stats(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, error_stats_service.ErrorGroupStats) for i in results) - - pages = list(client.list_group_stats(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -def test_list_events_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_events in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.list_events] = mock_rpc - - request = {} - client.list_events(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_events(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_list_events_rest_required_fields( - request_type=error_stats_service.ListEventsRequest, -): - transport_class = transports.ErrorStatsServiceRestTransport - - request_init = {} - request_init["project_name"] = "" - request_init["group_id"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - assert "groupId" not in jsonified_request - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_events._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - assert "groupId" in jsonified_request - assert jsonified_request["groupId"] == request_init["group_id"] - - jsonified_request["projectName"] = "project_name_value" - jsonified_request["groupId"] = "group_id_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_events._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "group_id", - "page_size", - "page_token", - "service_filter", - "time_range", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "projectName" in jsonified_request - assert jsonified_request["projectName"] == "project_name_value" - assert "groupId" in jsonified_request - assert jsonified_request["groupId"] == "group_id_value" - - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = error_stats_service.ListEventsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = error_stats_service.ListEventsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - response = client.list_events(request) - - expected_params = [ - ( - "groupId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_list_events_rest_unset_required_fields(): - transport = transports.ErrorStatsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.list_events._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "groupId", - "pageSize", - "pageToken", - "serviceFilter", - "timeRange", - ) - ) - & set( - ( - "projectName", - "groupId", - ) - ) - ) - - -def test_list_events_rest_flattened(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = error_stats_service.ListEventsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"project_name": "projects/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - project_name="project_name_value", - group_id="group_id_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = error_stats_service.ListEventsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.list_events(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1beta1/{project_name=projects/*}/events" % client.transport._host, - args[1], - ) - - -def test_list_events_rest_flattened_error(transport: str = "rest"): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_events( - error_stats_service.ListEventsRequest(), - project_name="project_name_value", - group_id="group_id_value", - ) - - -def test_list_events_rest_pager(transport: str = "rest"): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - common.ErrorEvent(), - common.ErrorEvent(), - ], - next_page_token="abc", - ), - error_stats_service.ListEventsResponse( - error_events=[], - next_page_token="def", - ), - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - ], - next_page_token="ghi", - ), - error_stats_service.ListEventsResponse( - error_events=[ - common.ErrorEvent(), - common.ErrorEvent(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - error_stats_service.ListEventsResponse.to_json(x) for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"project_name": "projects/sample1"} - - pager = client.list_events(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, common.ErrorEvent) for i in results) - - pages = list(client.list_events(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -def test_delete_events_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.delete_events in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[client._transport.delete_events] = mock_rpc - - request = {} - client.delete_events(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.delete_events(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_delete_events_rest_required_fields( - request_type=error_stats_service.DeleteEventsRequest, -): - transport_class = transports.ErrorStatsServiceRestTransport - - request_init = {} - request_init["project_name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_events._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["projectName"] = "project_name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_events._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "projectName" in jsonified_request - assert jsonified_request["projectName"] == "project_name_value" - - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = error_stats_service.DeleteEventsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "delete", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = error_stats_service.DeleteEventsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - response = client.delete_events(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_delete_events_rest_unset_required_fields(): - transport = transports.ErrorStatsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.delete_events._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("projectName",))) - - -def test_delete_events_rest_flattened(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = error_stats_service.DeleteEventsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"project_name": "projects/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - project_name="project_name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = error_stats_service.DeleteEventsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.delete_events(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1beta1/{project_name=projects/*}/events" % client.transport._host, - args[1], - ) - - -def test_delete_events_rest_flattened_error(transport: str = "rest"): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_events( - error_stats_service.DeleteEventsRequest(), - project_name="project_name_value", - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.ErrorStatsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.ErrorStatsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ErrorStatsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.ErrorStatsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ErrorStatsServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ErrorStatsServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.ErrorStatsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ErrorStatsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.ErrorStatsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = ErrorStatsServiceClient(transport=transport) - assert client.transport is transport - - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.ErrorStatsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.ErrorStatsServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ErrorStatsServiceGrpcTransport, - transports.ErrorStatsServiceGrpcAsyncIOTransport, - transports.ErrorStatsServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - -def test_transport_kind_grpc(): - transport = ErrorStatsServiceClient.get_transport_class("grpc")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "grpc" - - -def test_initialize_client_w_grpc(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_group_stats_empty_call_grpc(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_group_stats), "__call__") as call: - call.return_value = error_stats_service.ListGroupStatsResponse() - client.list_group_stats(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_stats_service.ListGroupStatsRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_events_empty_call_grpc(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_events), "__call__") as call: - call.return_value = error_stats_service.ListEventsResponse() - client.list_events(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_stats_service.ListEventsRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_events_empty_call_grpc(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.delete_events), "__call__") as call: - call.return_value = error_stats_service.DeleteEventsResponse() - client.delete_events(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_stats_service.DeleteEventsRequest() - - assert args[0] == request_msg - - -def test_transport_kind_grpc_asyncio(): - transport = ErrorStatsServiceAsyncClient.get_transport_class("grpc_asyncio")( - credentials=async_anonymous_credentials() - ) - assert transport.kind == "grpc_asyncio" - - -def test_initialize_client_w_grpc_asyncio(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), transport="grpc_asyncio" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_group_stats_empty_call_grpc_asyncio(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_group_stats), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - error_stats_service.ListGroupStatsResponse( - next_page_token="next_page_token_value", - ) - ) - await client.list_group_stats(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_stats_service.ListGroupStatsRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_events_empty_call_grpc_asyncio(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_events), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - error_stats_service.ListEventsResponse( - next_page_token="next_page_token_value", - ) - ) - await client.list_events(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_stats_service.ListEventsRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_delete_events_empty_call_grpc_asyncio(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.delete_events), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - error_stats_service.DeleteEventsResponse() - ) - await client.delete_events(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_stats_service.DeleteEventsRequest() - - assert args[0] == request_msg - - -def test_transport_kind_rest(): - transport = ErrorStatsServiceClient.get_transport_class("rest")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "rest" - - -def test_list_group_stats_rest_bad_request( - request_type=error_stats_service.ListGroupStatsRequest, -): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {"project_name": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = mock.Mock() - json_return_value = "" - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_group_stats(request) - - -@pytest.mark.parametrize( - "request_type", - [ - error_stats_service.ListGroupStatsRequest, - dict, - ], -) -def test_list_group_stats_rest_call_success(request_type): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {"project_name": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = error_stats_service.ListGroupStatsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = error_stats_service.ListGroupStatsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_group_stats(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListGroupStatsPager) - assert response.next_page_token == "next_page_token_value" - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_group_stats_rest_interceptors(null_interceptor): - transport = transports.ErrorStatsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ErrorStatsServiceRestInterceptor(), - ) - client = ErrorStatsServiceClient(transport=transport) - - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ErrorStatsServiceRestInterceptor, "post_list_group_stats" - ) as post, mock.patch.object( - transports.ErrorStatsServiceRestInterceptor, - "post_list_group_stats_with_metadata", - ) as post_with_metadata, mock.patch.object( - transports.ErrorStatsServiceRestInterceptor, "pre_list_group_stats" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - post_with_metadata.assert_not_called() - pb_message = error_stats_service.ListGroupStatsRequest.pb( - error_stats_service.ListGroupStatsRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = error_stats_service.ListGroupStatsResponse.to_json( - error_stats_service.ListGroupStatsResponse() - ) - req.return_value.content = return_value - - request = error_stats_service.ListGroupStatsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = error_stats_service.ListGroupStatsResponse() - post_with_metadata.return_value = ( - error_stats_service.ListGroupStatsResponse(), - metadata, - ) - - client.list_group_stats( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - post_with_metadata.assert_called_once() - - -def test_list_events_rest_bad_request( - request_type=error_stats_service.ListEventsRequest, -): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {"project_name": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = mock.Mock() - json_return_value = "" - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_events(request) - - -@pytest.mark.parametrize( - "request_type", - [ - error_stats_service.ListEventsRequest, - dict, - ], -) -def test_list_events_rest_call_success(request_type): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {"project_name": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = error_stats_service.ListEventsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = error_stats_service.ListEventsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_events(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListEventsPager) - assert response.next_page_token == "next_page_token_value" - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_events_rest_interceptors(null_interceptor): - transport = transports.ErrorStatsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ErrorStatsServiceRestInterceptor(), - ) - client = ErrorStatsServiceClient(transport=transport) - - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ErrorStatsServiceRestInterceptor, "post_list_events" - ) as post, mock.patch.object( - transports.ErrorStatsServiceRestInterceptor, "post_list_events_with_metadata" - ) as post_with_metadata, mock.patch.object( - transports.ErrorStatsServiceRestInterceptor, "pre_list_events" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - post_with_metadata.assert_not_called() - pb_message = error_stats_service.ListEventsRequest.pb( - error_stats_service.ListEventsRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = error_stats_service.ListEventsResponse.to_json( - error_stats_service.ListEventsResponse() - ) - req.return_value.content = return_value - - request = error_stats_service.ListEventsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = error_stats_service.ListEventsResponse() - post_with_metadata.return_value = ( - error_stats_service.ListEventsResponse(), - metadata, - ) - - client.list_events( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - post_with_metadata.assert_called_once() - - -def test_delete_events_rest_bad_request( - request_type=error_stats_service.DeleteEventsRequest, -): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {"project_name": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = mock.Mock() - json_return_value = "" - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.delete_events(request) - - -@pytest.mark.parametrize( - "request_type", - [ - error_stats_service.DeleteEventsRequest, - dict, - ], -) -def test_delete_events_rest_call_success(request_type): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {"project_name": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = error_stats_service.DeleteEventsResponse() - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = error_stats_service.DeleteEventsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.delete_events(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, error_stats_service.DeleteEventsResponse) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_events_rest_interceptors(null_interceptor): - transport = transports.ErrorStatsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ErrorStatsServiceRestInterceptor(), - ) - client = ErrorStatsServiceClient(transport=transport) - - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ErrorStatsServiceRestInterceptor, "post_delete_events" - ) as post, mock.patch.object( - transports.ErrorStatsServiceRestInterceptor, "post_delete_events_with_metadata" - ) as post_with_metadata, mock.patch.object( - transports.ErrorStatsServiceRestInterceptor, "pre_delete_events" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - post_with_metadata.assert_not_called() - pb_message = error_stats_service.DeleteEventsRequest.pb( - error_stats_service.DeleteEventsRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = error_stats_service.DeleteEventsResponse.to_json( - error_stats_service.DeleteEventsResponse() - ) - req.return_value.content = return_value - - request = error_stats_service.DeleteEventsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = error_stats_service.DeleteEventsResponse() - post_with_metadata.return_value = ( - error_stats_service.DeleteEventsResponse(), - metadata, - ) - - client.delete_events( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - post_with_metadata.assert_called_once() - - -def test_initialize_client_w_rest(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_group_stats_empty_call_rest(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_group_stats), "__call__") as call: - client.list_group_stats(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_stats_service.ListGroupStatsRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_events_empty_call_rest(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.list_events), "__call__") as call: - client.list_events(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_stats_service.ListEventsRequest() - - assert args[0] == request_msg - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_delete_events_empty_call_rest(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object(type(client.transport.delete_events), "__call__") as call: - client.delete_events(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = error_stats_service.DeleteEventsRequest() - - assert args[0] == request_msg - - -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert isinstance( - client.transport, - transports.ErrorStatsServiceGrpcTransport, - ) - - -def test_error_stats_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.ErrorStatsServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json", - ) - - -def test_error_stats_service_base_transport(): - # Instantiate the base transport. - with mock.patch( - "google.cloud.errorreporting_v1beta1.services.error_stats_service.transports.ErrorStatsServiceTransport.__init__" - ) as Transport: - Transport.return_value = None - transport = transports.ErrorStatsServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - "list_group_stats", - "list_events", - "delete_events", - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - # Catch all for all remaining methods and properties - remainder = [ - "kind", - ] - for r in remainder: - with pytest.raises(NotImplementedError): - getattr(transport, r)() - - -def test_error_stats_service_base_transport_with_credentials_file(): - # Instantiate the base transport with a credentials file - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch( - "google.cloud.errorreporting_v1beta1.services.error_stats_service.transports.ErrorStatsServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ErrorStatsServiceTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with( - "credentials.json", - scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id="octopus", - ) - - -def test_error_stats_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( - "google.cloud.errorreporting_v1beta1.services.error_stats_service.transports.ErrorStatsServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ErrorStatsServiceTransport() - adc.assert_called_once() - - -def test_error_stats_service_auth_adc(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - ErrorStatsServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ErrorStatsServiceGrpcTransport, - transports.ErrorStatsServiceGrpcAsyncIOTransport, - ], -) -def test_error_stats_service_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ErrorStatsServiceGrpcTransport, - transports.ErrorStatsServiceGrpcAsyncIOTransport, - transports.ErrorStatsServiceRestTransport, - ], -) -def test_error_stats_service_transport_auth_gdch_credentials(transport_class): - host = "https://language.com" - api_audience_tests = [None, "https://language2.com"] - api_audience_expect = [host, "https://language2.com"] - for t, e in zip(api_audience_tests, api_audience_expect): - with mock.patch.object(google.auth, "default", autospec=True) as adc: - gdch_mock = mock.MagicMock() - type(gdch_mock).with_gdch_audience = mock.PropertyMock( - return_value=gdch_mock - ) - adc.return_value = (gdch_mock, None) - transport_class(host=host, api_audience=t) - gdch_mock.with_gdch_audience.assert_called_once_with(e) - - -@pytest.mark.parametrize( - "transport_class,grpc_helpers", - [ - (transports.ErrorStatsServiceGrpcTransport, grpc_helpers), - (transports.ErrorStatsServiceGrpcAsyncIOTransport, grpc_helpers_async), - ], -) -def test_error_stats_service_transport_create_channel(transport_class, grpc_helpers): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object( - google.auth, "default", autospec=True - ) as adc, mock.patch.object( - grpc_helpers, "create_channel", autospec=True - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - adc.return_value = (creds, None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - - create_channel.assert_called_with( - "clouderrorreporting.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - scopes=["1", "2"], - default_host="clouderrorreporting.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ErrorStatsServiceGrpcTransport, - transports.ErrorStatsServiceGrpcAsyncIOTransport, - ], -) -def test_error_stats_service_grpc_transport_client_cert_source_for_mtls( - transport_class, -): - cred = ga_credentials.AnonymousCredentials() - - # Check ssl_channel_credentials is used if provided. - with mock.patch.object(transport_class, "create_channel") as mock_create_channel: - mock_ssl_channel_creds = mock.Mock() - transport_class( - host="squid.clam.whelk", - credentials=cred, - ssl_channel_credentials=mock_ssl_channel_creds, - ) - mock_create_channel.assert_called_once_with( - "squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_channel_creds, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls - # is used. - with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): - with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: - transport_class( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback, - ) - expected_cert, expected_key = client_cert_source_callback() - mock_ssl_cred.assert_called_once_with( - certificate_chain=expected_cert, private_key=expected_key - ) - - -def test_error_stats_service_http_transport_client_cert_source_for_mtls(): - cred = ga_credentials.AnonymousCredentials() - with mock.patch( - "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" - ) as mock_configure_mtls_channel: - transports.ErrorStatsServiceRestTransport( - credentials=cred, client_cert_source_for_mtls=client_cert_source_callback - ) - mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) - - -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "grpc_asyncio", - "rest", - ], -) -def test_error_stats_service_host_no_port(transport_name): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions( - api_endpoint="clouderrorreporting.googleapis.com" - ), - transport=transport_name, - ) - assert client.transport._host == ( - "clouderrorreporting.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://clouderrorreporting.googleapis.com" - ) - - -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "grpc_asyncio", - "rest", - ], -) -def test_error_stats_service_host_with_port(transport_name): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions( - api_endpoint="clouderrorreporting.googleapis.com:8000" - ), - transport=transport_name, - ) - assert client.transport._host == ( - "clouderrorreporting.googleapis.com:8000" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://clouderrorreporting.googleapis.com:8000" - ) - - -@pytest.mark.parametrize( - "transport_name", - [ - "rest", - ], -) -def test_error_stats_service_client_transport_session_collision(transport_name): - creds1 = ga_credentials.AnonymousCredentials() - creds2 = ga_credentials.AnonymousCredentials() - client1 = ErrorStatsServiceClient( - credentials=creds1, - transport=transport_name, - ) - client2 = ErrorStatsServiceClient( - credentials=creds2, - transport=transport_name, - ) - session1 = client1.transport.list_group_stats._session - session2 = client2.transport.list_group_stats._session - assert session1 != session2 - session1 = client1.transport.list_events._session - session2 = client2.transport.list_events._session - assert session1 != session2 - session1 = client1.transport.delete_events._session - session2 = client2.transport.delete_events._session - assert session1 != session2 - - -def test_error_stats_service_grpc_transport_channel(): - channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.ErrorStatsServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -def test_error_stats_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.ErrorStatsServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.filterwarnings("ignore::FutureWarning") -@pytest.mark.parametrize( - "transport_class", - [ - transports.ErrorStatsServiceGrpcTransport, - transports.ErrorStatsServiceGrpcAsyncIOTransport, - ], -) -def test_error_stats_service_transport_channel_mtls_with_client_cert_source( - transport_class, -): - with mock.patch( - "grpc.ssl_channel_credentials", autospec=True - ) as grpc_ssl_channel_cred: - with mock.patch.object( - transport_class, "create_channel" - ) as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = ga_credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - assert transport._ssl_channel_credentials == mock_ssl_cred - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize( - "transport_class", - [ - transports.ErrorStatsServiceGrpcTransport, - transports.ErrorStatsServiceGrpcAsyncIOTransport, - ], -) -def test_error_stats_service_transport_channel_mtls_with_adc(transport_class): - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - with mock.patch.object( - transport_class, "create_channel" - ) as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_error_group_path(): - project = "squid" - group = "clam" - expected = "projects/{project}/groups/{group}".format( - project=project, - group=group, - ) - actual = ErrorStatsServiceClient.error_group_path(project, group) - assert expected == actual - - -def test_parse_error_group_path(): - expected = { - "project": "whelk", - "group": "octopus", - } - path = ErrorStatsServiceClient.error_group_path(**expected) - - # Check that the path construction is reversible. - actual = ErrorStatsServiceClient.parse_error_group_path(path) - assert expected == actual - - -def test_common_billing_account_path(): - billing_account = "oyster" - expected = "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - actual = ErrorStatsServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "nudibranch", - } - path = ErrorStatsServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = ErrorStatsServiceClient.parse_common_billing_account_path(path) - assert expected == actual - - -def test_common_folder_path(): - folder = "cuttlefish" - expected = "folders/{folder}".format( - folder=folder, - ) - actual = ErrorStatsServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "mussel", - } - path = ErrorStatsServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = ErrorStatsServiceClient.parse_common_folder_path(path) - assert expected == actual - - -def test_common_organization_path(): - organization = "winkle" - expected = "organizations/{organization}".format( - organization=organization, - ) - actual = ErrorStatsServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "nautilus", - } - path = ErrorStatsServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = ErrorStatsServiceClient.parse_common_organization_path(path) - assert expected == actual - - -def test_common_project_path(): - project = "scallop" - expected = "projects/{project}".format( - project=project, - ) - actual = ErrorStatsServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "abalone", - } - path = ErrorStatsServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = ErrorStatsServiceClient.parse_common_project_path(path) - assert expected == actual - - -def test_common_location_path(): - project = "squid" - location = "clam" - expected = "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - actual = ErrorStatsServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "whelk", - "location": "octopus", - } - path = ErrorStatsServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = ErrorStatsServiceClient.parse_common_location_path(path) - assert expected == actual - - -def test_client_with_default_client_info(): - client_info = gapic_v1.client_info.ClientInfo() - - with mock.patch.object( - transports.ErrorStatsServiceTransport, "_prep_wrapped_messages" - ) as prep: - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object( - transports.ErrorStatsServiceTransport, "_prep_wrapped_messages" - ) as prep: - transport_class = ErrorStatsServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -def test_transport_close_grpc(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc" - ) - with mock.patch.object( - type(getattr(client.transport, "_grpc_channel")), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -@pytest.mark.asyncio -async def test_transport_close_grpc_asyncio(): - client = ErrorStatsServiceAsyncClient( - credentials=async_anonymous_credentials(), transport="grpc_asyncio" - ) - with mock.patch.object( - type(getattr(client.transport, "_grpc_channel")), "close" - ) as close: - async with client: - close.assert_not_called() - close.assert_called_once() - - -def test_transport_close_rest(): - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - with mock.patch.object( - type(getattr(client.transport, "_session")), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -def test_client_ctx(): - transports = [ - "rest", - "grpc", - ] - for transport in transports: - client = ErrorStatsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - # Test client calls underlying transport. - with mock.patch.object(type(client.transport), "close") as close: - close.assert_not_called() - with client: - pass - close.assert_called() - - -@pytest.mark.parametrize( - "client_class,transport_class", - [ - (ErrorStatsServiceClient, transports.ErrorStatsServiceGrpcTransport), - ( - ErrorStatsServiceAsyncClient, - transports.ErrorStatsServiceGrpcAsyncIOTransport, - ), - ], -) -def test_api_key_credentials(client_class, transport_class): - with mock.patch.object( - google.auth._default, "get_api_key_credentials", create=True - ) as get_api_key_credentials: - mock_cred = mock.Mock() - get_api_key_credentials.return_value = mock_cred - options = client_options.ClientOptions() - options.api_key = "api_key" - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=mock_cred, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) diff --git a/tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py b/tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py deleted file mode 100644 index dd0d6be0..00000000 --- a/tests/unit/gapic/errorreporting_v1beta1/test_report_errors_service.py +++ /dev/null @@ -1,3001 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import os - -# try/except added for compatibility with python < 3.8 -try: - from unittest import mock - from unittest.mock import AsyncMock # pragma: NO COVER -except ImportError: # pragma: NO COVER - import mock - -import grpc -from grpc.experimental import aio -from collections.abc import Iterable, AsyncIterable -from google.protobuf import json_format -import json -import math -import pytest -from collections.abc import Sequence, Mapping -from google.api_core import api_core_version -from proto.marshal.rules.dates import DurationRule, TimestampRule -from proto.marshal.rules import wrappers -from requests import Response -from requests import Request, PreparedRequest -from requests.sessions import Session -from google.protobuf import json_format - -try: - from google.auth.aio import credentials as ga_credentials_async - - HAS_GOOGLE_AUTH_AIO = True -except ImportError: # pragma: NO COVER - HAS_GOOGLE_AUTH_AIO = False - -from google.api_core import client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers -from google.api_core import grpc_helpers_async -from google.api_core import path_template -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.cloud.errorreporting_v1beta1.services.report_errors_service import ( - ReportErrorsServiceAsyncClient, -) -from google.cloud.errorreporting_v1beta1.services.report_errors_service import ( - ReportErrorsServiceClient, -) -from google.cloud.errorreporting_v1beta1.services.report_errors_service import ( - transports, -) -from google.cloud.errorreporting_v1beta1.types import common -from google.cloud.errorreporting_v1beta1.types import report_errors_service -from google.oauth2 import service_account -import google.auth -import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore - - -CRED_INFO_JSON = { - "credential_source": "/path/to/file", - "credential_type": "service account credentials", - "principal": "service-account@example.com", -} -CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) - - -async def mock_async_gen(data, chunk_size=1): - for i in range(0, len(data)): # pragma: NO COVER - chunk = data[i : i + chunk_size] - yield chunk.encode("utf-8") - - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - - -# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. -# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. -def async_anonymous_credentials(): - if HAS_GOOGLE_AUTH_AIO: - return ga_credentials_async.AnonymousCredentials() - return ga_credentials.AnonymousCredentials() - - -# If default endpoint is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint(client): - return ( - "foo.googleapis.com" - if ("localhost" in client.DEFAULT_ENDPOINT) - else client.DEFAULT_ENDPOINT - ) - - -# If default endpoint template is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint template so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint_template(client): - return ( - "test.{UNIVERSE_DOMAIN}" - if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) - else client._DEFAULT_ENDPOINT_TEMPLATE - ) - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert ReportErrorsServiceClient._get_default_mtls_endpoint(None) is None - assert ( - ReportErrorsServiceClient._get_default_mtls_endpoint(api_endpoint) - == api_mtls_endpoint - ) - assert ( - ReportErrorsServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) - == api_mtls_endpoint - ) - assert ( - ReportErrorsServiceClient._get_default_mtls_endpoint(sandbox_endpoint) - == sandbox_mtls_endpoint - ) - assert ( - ReportErrorsServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) - == sandbox_mtls_endpoint - ) - assert ( - ReportErrorsServiceClient._get_default_mtls_endpoint(non_googleapi) - == non_googleapi - ) - - -def test__read_environment_variables(): - assert ReportErrorsServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert ReportErrorsServiceClient._read_environment_variables() == ( - True, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - assert ReportErrorsServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with pytest.raises(ValueError) as excinfo: - ReportErrorsServiceClient._read_environment_variables() - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - else: - assert ReportErrorsServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - assert ReportErrorsServiceClient._read_environment_variables() == ( - False, - "never", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - assert ReportErrorsServiceClient._read_environment_variables() == ( - False, - "always", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): - assert ReportErrorsServiceClient._read_environment_variables() == ( - False, - "auto", - None, - ) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - ReportErrorsServiceClient._read_environment_variables() - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): - assert ReportErrorsServiceClient._read_environment_variables() == ( - False, - "auto", - "foo.com", - ) - - -def test_use_client_cert_effective(): - # Test case 1: Test when `should_use_client_cert` returns True. - # We mock the `should_use_client_cert` function to simulate a scenario where - # the google-auth library supports automatic mTLS and determines that a - # client certificate should be used. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch( - "google.auth.transport.mtls.should_use_client_cert", return_value=True - ): - assert ReportErrorsServiceClient._use_client_cert_effective() is True - - # Test case 2: Test when `should_use_client_cert` returns False. - # We mock the `should_use_client_cert` function to simulate a scenario where - # the google-auth library supports automatic mTLS and determines that a - # client certificate should NOT be used. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch( - "google.auth.transport.mtls.should_use_client_cert", return_value=False - ): - assert ReportErrorsServiceClient._use_client_cert_effective() is False - - # Test case 3: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert ReportErrorsServiceClient._use_client_cert_effective() is True - - # Test case 4: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"} - ): - assert ReportErrorsServiceClient._use_client_cert_effective() is False - - # Test case 5: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}): - assert ReportErrorsServiceClient._use_client_cert_effective() is True - - # Test case 6: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"} - ): - assert ReportErrorsServiceClient._use_client_cert_effective() is False - - # Test case 7: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}): - assert ReportErrorsServiceClient._use_client_cert_effective() is True - - # Test case 8: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"} - ): - assert ReportErrorsServiceClient._use_client_cert_effective() is False - - # Test case 9: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set. - # In this case, the method should return False, which is the default value. - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, clear=True): - assert ReportErrorsServiceClient._use_client_cert_effective() is False - - # Test case 10: Test when `should_use_client_cert` is unavailable and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. - # The method should raise a ValueError as the environment variable must be either - # "true" or "false". - if not hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} - ): - with pytest.raises(ValueError): - ReportErrorsServiceClient._use_client_cert_effective() - - # Test case 11: Test when `should_use_client_cert` is available and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value. - # The method should return False as the environment variable is set to an invalid value. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"} - ): - assert ReportErrorsServiceClient._use_client_cert_effective() is False - - # Test case 12: Test when `should_use_client_cert` is available and the - # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also, - # the GOOGLE_API_CONFIG environment variable is unset. - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}): - with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}): - assert ReportErrorsServiceClient._use_client_cert_effective() is False - - -def test__get_client_cert_source(): - mock_provided_cert_source = mock.Mock() - mock_default_cert_source = mock.Mock() - - assert ReportErrorsServiceClient._get_client_cert_source(None, False) is None - assert ( - ReportErrorsServiceClient._get_client_cert_source( - mock_provided_cert_source, False - ) - is None - ) - assert ( - ReportErrorsServiceClient._get_client_cert_source( - mock_provided_cert_source, True - ) - == mock_provided_cert_source - ) - - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", return_value=True - ): - with mock.patch( - "google.auth.transport.mtls.default_client_cert_source", - return_value=mock_default_cert_source, - ): - assert ( - ReportErrorsServiceClient._get_client_cert_source(None, True) - is mock_default_cert_source - ) - assert ( - ReportErrorsServiceClient._get_client_cert_source( - mock_provided_cert_source, "true" - ) - is mock_provided_cert_source - ) - - -@mock.patch.object( - ReportErrorsServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ReportErrorsServiceClient), -) -@mock.patch.object( - ReportErrorsServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ReportErrorsServiceAsyncClient), -) -def test__get_api_endpoint(): - api_override = "foo.com" - mock_client_cert_source = mock.Mock() - default_universe = ReportErrorsServiceClient._DEFAULT_UNIVERSE - default_endpoint = ReportErrorsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=default_universe - ) - mock_universe = "bar.com" - mock_endpoint = ReportErrorsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=mock_universe - ) - - assert ( - ReportErrorsServiceClient._get_api_endpoint( - api_override, mock_client_cert_source, default_universe, "always" - ) - == api_override - ) - assert ( - ReportErrorsServiceClient._get_api_endpoint( - None, mock_client_cert_source, default_universe, "auto" - ) - == ReportErrorsServiceClient.DEFAULT_MTLS_ENDPOINT - ) - assert ( - ReportErrorsServiceClient._get_api_endpoint( - None, None, default_universe, "auto" - ) - == default_endpoint - ) - assert ( - ReportErrorsServiceClient._get_api_endpoint( - None, None, default_universe, "always" - ) - == ReportErrorsServiceClient.DEFAULT_MTLS_ENDPOINT - ) - assert ( - ReportErrorsServiceClient._get_api_endpoint( - None, mock_client_cert_source, default_universe, "always" - ) - == ReportErrorsServiceClient.DEFAULT_MTLS_ENDPOINT - ) - assert ( - ReportErrorsServiceClient._get_api_endpoint(None, None, mock_universe, "never") - == mock_endpoint - ) - assert ( - ReportErrorsServiceClient._get_api_endpoint( - None, None, default_universe, "never" - ) - == default_endpoint - ) - - with pytest.raises(MutualTLSChannelError) as excinfo: - ReportErrorsServiceClient._get_api_endpoint( - None, mock_client_cert_source, mock_universe, "auto" - ) - assert ( - str(excinfo.value) - == "mTLS is not supported in any universe other than googleapis.com." - ) - - -def test__get_universe_domain(): - client_universe_domain = "foo.com" - universe_domain_env = "bar.com" - - assert ( - ReportErrorsServiceClient._get_universe_domain( - client_universe_domain, universe_domain_env - ) - == client_universe_domain - ) - assert ( - ReportErrorsServiceClient._get_universe_domain(None, universe_domain_env) - == universe_domain_env - ) - assert ( - ReportErrorsServiceClient._get_universe_domain(None, None) - == ReportErrorsServiceClient._DEFAULT_UNIVERSE - ) - - with pytest.raises(ValueError) as excinfo: - ReportErrorsServiceClient._get_universe_domain("", None) - assert str(excinfo.value) == "Universe Domain cannot be an empty string." - - -@pytest.mark.parametrize( - "error_code,cred_info_json,show_cred_info", - [ - (401, CRED_INFO_JSON, True), - (403, CRED_INFO_JSON, True), - (404, CRED_INFO_JSON, True), - (500, CRED_INFO_JSON, False), - (401, None, False), - (403, None, False), - (404, None, False), - (500, None, False), - ], -) -def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): - cred = mock.Mock(["get_cred_info"]) - cred.get_cred_info = mock.Mock(return_value=cred_info_json) - client = ReportErrorsServiceClient(credentials=cred) - client._transport._credentials = cred - - error = core_exceptions.GoogleAPICallError("message", details=["foo"]) - error.code = error_code - - client._add_cred_info_for_auth_errors(error) - if show_cred_info: - assert error.details == ["foo", CRED_INFO_STRING] - else: - assert error.details == ["foo"] - - -@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) -def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): - cred = mock.Mock([]) - assert not hasattr(cred, "get_cred_info") - client = ReportErrorsServiceClient(credentials=cred) - client._transport._credentials = cred - - error = core_exceptions.GoogleAPICallError("message", details=[]) - error.code = error_code - - client._add_cred_info_for_auth_errors(error) - assert error.details == [] - - -@pytest.mark.parametrize( - "client_class,transport_name", - [ - (ReportErrorsServiceClient, "grpc"), - (ReportErrorsServiceAsyncClient, "grpc_asyncio"), - (ReportErrorsServiceClient, "rest"), - ], -) -def test_report_errors_service_client_from_service_account_info( - client_class, transport_name -): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object( - service_account.Credentials, "from_service_account_info" - ) as factory: - factory.return_value = creds - info = {"valid": True} - client = client_class.from_service_account_info(info, transport=transport_name) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == ( - "clouderrorreporting.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://clouderrorreporting.googleapis.com" - ) - - -@pytest.mark.parametrize( - "transport_class,transport_name", - [ - (transports.ReportErrorsServiceGrpcTransport, "grpc"), - (transports.ReportErrorsServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (transports.ReportErrorsServiceRestTransport, "rest"), - ], -) -def test_report_errors_service_client_service_account_always_use_jwt( - transport_class, transport_name -): - with mock.patch.object( - service_account.Credentials, "with_always_use_jwt_access", create=True - ) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=True) - use_jwt.assert_called_once_with(True) - - with mock.patch.object( - service_account.Credentials, "with_always_use_jwt_access", create=True - ) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=False) - use_jwt.assert_not_called() - - -@pytest.mark.parametrize( - "client_class,transport_name", - [ - (ReportErrorsServiceClient, "grpc"), - (ReportErrorsServiceAsyncClient, "grpc_asyncio"), - (ReportErrorsServiceClient, "rest"), - ], -) -def test_report_errors_service_client_from_service_account_file( - client_class, transport_name -): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object( - service_account.Credentials, "from_service_account_file" - ) as factory: - factory.return_value = creds - client = client_class.from_service_account_file( - "dummy/file/path.json", transport=transport_name - ) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - client = client_class.from_service_account_json( - "dummy/file/path.json", transport=transport_name - ) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == ( - "clouderrorreporting.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://clouderrorreporting.googleapis.com" - ) - - -def test_report_errors_service_client_get_transport_class(): - transport = ReportErrorsServiceClient.get_transport_class() - available_transports = [ - transports.ReportErrorsServiceGrpcTransport, - transports.ReportErrorsServiceRestTransport, - ] - assert transport in available_transports - - transport = ReportErrorsServiceClient.get_transport_class("grpc") - assert transport == transports.ReportErrorsServiceGrpcTransport - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name", - [ - ( - ReportErrorsServiceClient, - transports.ReportErrorsServiceGrpcTransport, - "grpc", - ), - ( - ReportErrorsServiceAsyncClient, - transports.ReportErrorsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - ), - ( - ReportErrorsServiceClient, - transports.ReportErrorsServiceRestTransport, - "rest", - ), - ], -) -@mock.patch.object( - ReportErrorsServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ReportErrorsServiceClient), -) -@mock.patch.object( - ReportErrorsServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ReportErrorsServiceAsyncClient), -) -def test_report_errors_service_client_client_options( - client_class, transport_class, transport_name -): - # Check that if channel is provided we won't create a new one. - with mock.patch.object(ReportErrorsServiceClient, "get_transport_class") as gtc: - transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) - client = client_class(transport=transport) - gtc.assert_not_called() - - # Check that if channel is provided via str we will create a new one. - with mock.patch.object(ReportErrorsServiceClient, "get_transport_class") as gtc: - client = client_class(transport=transport_name) - gtc.assert_called() - - # Check the case api_endpoint is provided. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - client = client_class(transport=transport_name) - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - # Check the case api_endpoint is provided - options = client_options.ClientOptions( - api_audience="https://language.googleapis.com" - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience="https://language.googleapis.com", - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,use_client_cert_env", - [ - ( - ReportErrorsServiceClient, - transports.ReportErrorsServiceGrpcTransport, - "grpc", - "true", - ), - ( - ReportErrorsServiceAsyncClient, - transports.ReportErrorsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "true", - ), - ( - ReportErrorsServiceClient, - transports.ReportErrorsServiceGrpcTransport, - "grpc", - "false", - ), - ( - ReportErrorsServiceAsyncClient, - transports.ReportErrorsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - "false", - ), - ( - ReportErrorsServiceClient, - transports.ReportErrorsServiceRestTransport, - "rest", - "true", - ), - ( - ReportErrorsServiceClient, - transports.ReportErrorsServiceRestTransport, - "rest", - "false", - ), - ], -) -@mock.patch.object( - ReportErrorsServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ReportErrorsServiceClient), -) -@mock.patch.object( - ReportErrorsServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ReportErrorsServiceAsyncClient), -) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_report_errors_service_client_mtls_env_auto( - client_class, transport_class, transport_name, use_client_cert_env -): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - options = client_options.ClientOptions( - client_cert_source=client_cert_source_callback - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - - if use_client_cert_env == "false": - expected_client_cert_source = None - expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ) - else: - expected_client_cert_source = client_cert_source_callback - expected_host = client.DEFAULT_MTLS_ENDPOINT - - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, - ): - with mock.patch( - "google.auth.transport.mtls.default_client_cert_source", - return_value=client_cert_source_callback, - ): - if use_client_cert_env == "false": - expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ) - expected_client_cert_source = None - else: - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_client_cert_source = client_cert_source_callback - - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, - ): - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize( - "client_class", [ReportErrorsServiceClient, ReportErrorsServiceAsyncClient] -) -@mock.patch.object( - ReportErrorsServiceClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(ReportErrorsServiceClient), -) -@mock.patch.object( - ReportErrorsServiceAsyncClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(ReportErrorsServiceAsyncClient), -) -def test_report_errors_service_client_get_mtls_endpoint_and_cert_source(client_class): - mock_client_cert_source = mock.Mock() - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint - ) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( - options - ) - assert api_endpoint == mock_api_endpoint - assert cert_source == mock_client_cert_source - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint - ) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( - options - ) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "Unsupported". - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, - api_endpoint=mock_api_endpoint, - ) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( - options - ) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset. - test_cases = [ - ( - # With workloads present in config, mTLS is enabled. - { - "version": 1, - "cert_configs": { - "workload": { - "cert_path": "path/to/cert/file", - "key_path": "path/to/key/file", - } - }, - }, - mock_client_cert_source, - ), - ( - # With workloads not present in config, mTLS is disabled. - { - "version": 1, - "cert_configs": {}, - }, - None, - ), - ] - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - for config_data, expected_cert_source in test_cases: - env = os.environ.copy() - env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None) - with mock.patch.dict(os.environ, env, clear=True): - config_filename = "mock_certificate_config.json" - config_file_content = json.dumps(config_data) - m = mock.mock_open(read_data=config_file_content) - with mock.patch("builtins.open", m): - with mock.patch.dict( - os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} - ): - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, - api_endpoint=mock_api_endpoint, - ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is expected_cert_source - - # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty). - test_cases = [ - ( - # With workloads present in config, mTLS is enabled. - { - "version": 1, - "cert_configs": { - "workload": { - "cert_path": "path/to/cert/file", - "key_path": "path/to/key/file", - } - }, - }, - mock_client_cert_source, - ), - ( - # With workloads not present in config, mTLS is disabled. - { - "version": 1, - "cert_configs": {}, - }, - None, - ), - ] - if hasattr(google.auth.transport.mtls, "should_use_client_cert"): - for config_data, expected_cert_source in test_cases: - env = os.environ.copy() - env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "") - with mock.patch.dict(os.environ, env, clear=True): - config_filename = "mock_certificate_config.json" - config_file_content = json.dumps(config_data) - m = mock.mock_open(read_data=config_file_content) - with mock.patch("builtins.open", m): - with mock.patch.dict( - os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename} - ): - mock_api_endpoint = "foo" - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, - api_endpoint=mock_api_endpoint, - ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is expected_cert_source - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, - ): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, - ): - with mock.patch( - "google.auth.transport.mtls.default_client_cert_source", - return_value=mock_client_cert_source, - ): - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source == mock_client_cert_source - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert ( - str(excinfo.value) - == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - -@pytest.mark.parametrize( - "client_class", [ReportErrorsServiceClient, ReportErrorsServiceAsyncClient] -) -@mock.patch.object( - ReportErrorsServiceClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ReportErrorsServiceClient), -) -@mock.patch.object( - ReportErrorsServiceAsyncClient, - "_DEFAULT_ENDPOINT_TEMPLATE", - modify_default_endpoint_template(ReportErrorsServiceAsyncClient), -) -def test_report_errors_service_client_client_api_endpoint(client_class): - mock_client_cert_source = client_cert_source_callback - api_override = "foo.com" - default_universe = ReportErrorsServiceClient._DEFAULT_UNIVERSE - default_endpoint = ReportErrorsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=default_universe - ) - mock_universe = "bar.com" - mock_endpoint = ReportErrorsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=mock_universe - ) - - # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", - # use ClientOptions.api_endpoint as the api endpoint regardless. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch( - "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" - ): - options = client_options.ClientOptions( - client_cert_source=mock_client_cert_source, api_endpoint=api_override - ) - client = client_class( - client_options=options, - credentials=ga_credentials.AnonymousCredentials(), - ) - assert client.api_endpoint == api_override - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", - # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - - # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), - # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, - # and ClientOptions.universe_domain="bar.com", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. - options = client_options.ClientOptions() - universe_exists = hasattr(options, "universe_domain") - if universe_exists: - options = client_options.ClientOptions(universe_domain=mock_universe) - client = client_class( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - else: - client = client_class( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - assert client.api_endpoint == ( - mock_endpoint if universe_exists else default_endpoint - ) - assert client.universe_domain == ( - mock_universe if universe_exists else default_universe - ) - - # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - options = client_options.ClientOptions() - if hasattr(options, "universe_domain"): - delattr(options, "universe_domain") - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - assert client.api_endpoint == default_endpoint - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name", - [ - ( - ReportErrorsServiceClient, - transports.ReportErrorsServiceGrpcTransport, - "grpc", - ), - ( - ReportErrorsServiceAsyncClient, - transports.ReportErrorsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - ), - ( - ReportErrorsServiceClient, - transports.ReportErrorsServiceRestTransport, - "rest", - ), - ], -) -def test_report_errors_service_client_client_options_scopes( - client_class, transport_class, transport_name -): - # Check the case scopes are provided. - options = client_options.ClientOptions( - scopes=["1", "2"], - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=["1", "2"], - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,grpc_helpers", - [ - ( - ReportErrorsServiceClient, - transports.ReportErrorsServiceGrpcTransport, - "grpc", - grpc_helpers, - ), - ( - ReportErrorsServiceAsyncClient, - transports.ReportErrorsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - grpc_helpers_async, - ), - ( - ReportErrorsServiceClient, - transports.ReportErrorsServiceRestTransport, - "rest", - None, - ), - ], -) -def test_report_errors_service_client_client_options_credentials_file( - client_class, transport_class, transport_name, grpc_helpers -): - # Check the case credentials file is provided. - options = client_options.ClientOptions(credentials_file="credentials.json") - - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -def test_report_errors_service_client_client_options_from_dict(): - with mock.patch( - "google.cloud.errorreporting_v1beta1.services.report_errors_service.transports.ReportErrorsServiceGrpcTransport.__init__" - ) as grpc_transport: - grpc_transport.return_value = None - client = ReportErrorsServiceClient( - client_options={"api_endpoint": "squid.clam.whelk"} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,grpc_helpers", - [ - ( - ReportErrorsServiceClient, - transports.ReportErrorsServiceGrpcTransport, - "grpc", - grpc_helpers, - ), - ( - ReportErrorsServiceAsyncClient, - transports.ReportErrorsServiceGrpcAsyncIOTransport, - "grpc_asyncio", - grpc_helpers_async, - ), - ], -) -def test_report_errors_service_client_create_channel_credentials_file( - client_class, transport_class, transport_name, grpc_helpers -): - # Check the case credentials file is provided. - options = client_options.ClientOptions(credentials_file="credentials.json") - - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # test that the credentials from file are saved and used as the credentials. - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch.object( - google.auth, "default", autospec=True - ) as adc, mock.patch.object( - grpc_helpers, "create_channel" - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - file_creds = ga_credentials.AnonymousCredentials() - load_creds.return_value = (file_creds, None) - adc.return_value = (creds, None) - client = client_class(client_options=options, transport=transport_name) - create_channel.assert_called_with( - "clouderrorreporting.googleapis.com:443", - credentials=file_creds, - credentials_file=None, - quota_project_id=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - scopes=None, - default_host="clouderrorreporting.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize( - "request_type", - [ - report_errors_service.ReportErrorEventRequest, - dict, - ], -) -def test_report_error_event(request_type, transport: str = "grpc"): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # 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: - # Designate an appropriate return value for the call. - call.return_value = report_errors_service.ReportErrorEventResponse() - response = client.report_error_event(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = report_errors_service.ReportErrorEventRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, report_errors_service.ReportErrorEventResponse) - - -def test_report_error_event_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = report_errors_service.ReportErrorEventRequest( - project_name="project_name_value", - ) - - # 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: - call.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client.report_error_event(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == report_errors_service.ReportErrorEventRequest( - project_name="project_name_value", - ) - - -def test_report_error_event_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.report_error_event in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.report_error_event - ] = mock_rpc - request = {} - client.report_error_event(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.report_error_event(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -@pytest.mark.asyncio -async def test_report_error_event_async_use_cached_wrapped_rpc( - transport: str = "grpc_asyncio", -): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = ReportErrorsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._client._transport.report_error_event - in client._client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[ - client._client._transport.report_error_event - ] = mock_rpc - - request = {} - await client.report_error_event(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.report_error_event(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -@pytest.mark.asyncio -async def test_report_error_event_async( - transport: str = "grpc_asyncio", - request_type=report_errors_service.ReportErrorEventRequest, -): - client = ReportErrorsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.report_error_event), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - report_errors_service.ReportErrorEventResponse() - ) - response = await client.report_error_event(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = report_errors_service.ReportErrorEventRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, report_errors_service.ReportErrorEventResponse) - - -@pytest.mark.asyncio -async def test_report_error_event_async_from_dict(): - await test_report_error_event_async(request_type=dict) - - -def test_report_error_event_field_headers(): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = report_errors_service.ReportErrorEventRequest() - - request.project_name = "project_name_value" - - # 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: - call.return_value = report_errors_service.ReportErrorEventResponse() - client.report_error_event(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "project_name=project_name_value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_report_error_event_field_headers_async(): - client = ReportErrorsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = report_errors_service.ReportErrorEventRequest() - - request.project_name = "project_name_value" - - # 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: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - report_errors_service.ReportErrorEventResponse() - ) - await client.report_error_event(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "project_name=project_name_value", - ) in kw["metadata"] - - -def test_report_error_event_flattened(): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # 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: - # Designate an appropriate return value for the call. - call.return_value = report_errors_service.ReportErrorEventResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.report_error_event( - project_name="project_name_value", - event=report_errors_service.ReportedErrorEvent( - event_time=timestamp_pb2.Timestamp(seconds=751) - ), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - arg = args[0].project_name - mock_val = "project_name_value" - assert arg == mock_val - arg = args[0].event - mock_val = report_errors_service.ReportedErrorEvent( - event_time=timestamp_pb2.Timestamp(seconds=751) - ) - assert arg == mock_val - - -def test_report_error_event_flattened_error(): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.report_error_event( - report_errors_service.ReportErrorEventRequest(), - project_name="project_name_value", - event=report_errors_service.ReportedErrorEvent( - event_time=timestamp_pb2.Timestamp(seconds=751) - ), - ) - - -@pytest.mark.asyncio -async def test_report_error_event_flattened_async(): - client = ReportErrorsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # 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: - # Designate an appropriate return value for the call. - call.return_value = report_errors_service.ReportErrorEventResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - report_errors_service.ReportErrorEventResponse() - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.report_error_event( - project_name="project_name_value", - event=report_errors_service.ReportedErrorEvent( - event_time=timestamp_pb2.Timestamp(seconds=751) - ), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - arg = args[0].project_name - mock_val = "project_name_value" - assert arg == mock_val - arg = args[0].event - mock_val = report_errors_service.ReportedErrorEvent( - event_time=timestamp_pb2.Timestamp(seconds=751) - ) - assert arg == mock_val - - -@pytest.mark.asyncio -async def test_report_error_event_flattened_error_async(): - client = ReportErrorsServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.report_error_event( - report_errors_service.ReportErrorEventRequest(), - project_name="project_name_value", - event=report_errors_service.ReportedErrorEvent( - event_time=timestamp_pb2.Timestamp(seconds=751) - ), - ) - - -def test_report_error_event_rest_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert ( - client._transport.report_error_event in client._transport._wrapped_methods - ) - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = ( - "foo" # operation_request.operation in compute client(s) expect a string. - ) - client._transport._wrapped_methods[ - client._transport.report_error_event - ] = mock_rpc - - request = {} - client.report_error_event(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.report_error_event(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - - -def test_report_error_event_rest_required_fields( - request_type=report_errors_service.ReportErrorEventRequest, -): - transport_class = transports.ReportErrorsServiceRestTransport - - request_init = {} - request_init["project_name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson(pb_request, use_integers_for_enums=False) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).report_error_event._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["projectName"] = "project_name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).report_error_event._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "projectName" in jsonified_request - assert jsonified_request["projectName"] == "project_name_value" - - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = report_errors_service.ReportErrorEventResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = report_errors_service.ReportErrorEventResponse.pb( - return_value - ) - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - response = client.report_error_event(request) - - expected_params = [("$alt", "json;enum-encoding=int")] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_report_error_event_rest_unset_required_fields(): - transport = transports.ReportErrorsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.report_error_event._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(()) - & set( - ( - "projectName", - "event", - ) - ) - ) - - -def test_report_error_event_rest_flattened(): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = report_errors_service.ReportErrorEventResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"project_name": "projects/sample1"} - - # get truthy value for each flattened field - mock_args = dict( - project_name="project_name_value", - event=report_errors_service.ReportedErrorEvent( - event_time=timestamp_pb2.Timestamp(seconds=751) - ), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - # Convert return value to protobuf type - return_value = report_errors_service.ReportErrorEventResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - - client.report_error_event(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1beta1/{project_name=projects/*}/events:report" - % client.transport._host, - args[1], - ) - - -def test_report_error_event_rest_flattened_error(transport: str = "rest"): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.report_error_event( - report_errors_service.ReportErrorEventRequest(), - project_name="project_name_value", - event=report_errors_service.ReportedErrorEvent( - event_time=timestamp_pb2.Timestamp(seconds=751) - ), - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.ReportErrorsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.ReportErrorsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ReportErrorsServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.ReportErrorsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ReportErrorsServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ReportErrorsServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.ReportErrorsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ReportErrorsServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.ReportErrorsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = ReportErrorsServiceClient(transport=transport) - assert client.transport is transport - - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.ReportErrorsServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.ReportErrorsServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ReportErrorsServiceGrpcTransport, - transports.ReportErrorsServiceGrpcAsyncIOTransport, - transports.ReportErrorsServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - -def test_transport_kind_grpc(): - transport = ReportErrorsServiceClient.get_transport_class("grpc")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "grpc" - - -def test_initialize_client_w_grpc(): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_report_error_event_empty_call_grpc(): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.report_error_event), "__call__" - ) as call: - call.return_value = report_errors_service.ReportErrorEventResponse() - client.report_error_event(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = report_errors_service.ReportErrorEventRequest() - - assert args[0] == request_msg - - -def test_transport_kind_grpc_asyncio(): - transport = ReportErrorsServiceAsyncClient.get_transport_class("grpc_asyncio")( - credentials=async_anonymous_credentials() - ) - assert transport.kind == "grpc_asyncio" - - -def test_initialize_client_w_grpc_asyncio(): - client = ReportErrorsServiceAsyncClient( - credentials=async_anonymous_credentials(), transport="grpc_asyncio" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_report_error_event_empty_call_grpc_asyncio(): - client = ReportErrorsServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.report_error_event), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - report_errors_service.ReportErrorEventResponse() - ) - await client.report_error_event(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = report_errors_service.ReportErrorEventRequest() - - assert args[0] == request_msg - - -def test_transport_kind_rest(): - transport = ReportErrorsServiceClient.get_transport_class("rest")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "rest" - - -def test_report_error_event_rest_bad_request( - request_type=report_errors_service.ReportErrorEventRequest, -): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - # send a request that will satisfy transcoding - request_init = {"project_name": "projects/sample1"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = mock.Mock() - json_return_value = "" - response_value.json = mock.Mock(return_value={}) - response_value.status_code = 400 - response_value.request = mock.Mock() - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.report_error_event(request) - - -@pytest.mark.parametrize( - "request_type", - [ - report_errors_service.ReportErrorEventRequest, - dict, - ], -) -def test_report_error_event_rest_call_success(request_type): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - # send a request that will satisfy transcoding - request_init = {"project_name": "projects/sample1"} - request_init["event"] = { - "event_time": {"seconds": 751, "nanos": 543}, - "service_context": { - "service": "service_value", - "version": "version_value", - "resource_type": "resource_type_value", - }, - "message": "message_value", - "context": { - "http_request": { - "method": "method_value", - "url": "url_value", - "user_agent": "user_agent_value", - "referrer": "referrer_value", - "response_status_code": 2156, - "remote_ip": "remote_ip_value", - }, - "user": "user_value", - "report_location": { - "file_path": "file_path_value", - "line_number": 1168, - "function_name": "function_name_value", - }, - }, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = report_errors_service.ReportErrorEventRequest.meta.fields["event"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["event"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["event"][field])): - del request_init["event"][field][i][subfield] - else: - del request_init["event"][field][subfield] - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = report_errors_service.ReportErrorEventResponse() - - # Wrap the value into a proper Response obj - response_value = mock.Mock() - response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = report_errors_service.ReportErrorEventResponse.pb(return_value) - json_return_value = json_format.MessageToJson(return_value) - response_value.content = json_return_value.encode("UTF-8") - req.return_value = response_value - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.report_error_event(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, report_errors_service.ReportErrorEventResponse) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_report_error_event_rest_interceptors(null_interceptor): - transport = transports.ReportErrorsServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None - if null_interceptor - else transports.ReportErrorsServiceRestInterceptor(), - ) - client = ReportErrorsServiceClient(transport=transport) - - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ReportErrorsServiceRestInterceptor, "post_report_error_event" - ) as post, mock.patch.object( - transports.ReportErrorsServiceRestInterceptor, - "post_report_error_event_with_metadata", - ) as post_with_metadata, mock.patch.object( - transports.ReportErrorsServiceRestInterceptor, "pre_report_error_event" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - post_with_metadata.assert_not_called() - pb_message = report_errors_service.ReportErrorEventRequest.pb( - report_errors_service.ReportErrorEventRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = mock.Mock() - req.return_value.status_code = 200 - req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = report_errors_service.ReportErrorEventResponse.to_json( - report_errors_service.ReportErrorEventResponse() - ) - req.return_value.content = return_value - - request = report_errors_service.ReportErrorEventRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = report_errors_service.ReportErrorEventResponse() - post_with_metadata.return_value = ( - report_errors_service.ReportErrorEventResponse(), - metadata, - ) - - client.report_error_event( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - post_with_metadata.assert_called_once() - - -def test_initialize_client_w_rest(): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_report_error_event_empty_call_rest(): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.report_error_event), "__call__" - ) as call: - client.report_error_event(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = report_errors_service.ReportErrorEventRequest() - - assert args[0] == request_msg - - -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert isinstance( - client.transport, - transports.ReportErrorsServiceGrpcTransport, - ) - - -def test_report_errors_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.ReportErrorsServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json", - ) - - -def test_report_errors_service_base_transport(): - # Instantiate the base transport. - with mock.patch( - "google.cloud.errorreporting_v1beta1.services.report_errors_service.transports.ReportErrorsServiceTransport.__init__" - ) as Transport: - Transport.return_value = None - transport = transports.ReportErrorsServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ("report_error_event",) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - # Catch all for all remaining methods and properties - remainder = [ - "kind", - ] - for r in remainder: - with pytest.raises(NotImplementedError): - getattr(transport, r)() - - -def test_report_errors_service_base_transport_with_credentials_file(): - # Instantiate the base transport with a credentials file - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch( - "google.cloud.errorreporting_v1beta1.services.report_errors_service.transports.ReportErrorsServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ReportErrorsServiceTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with( - "credentials.json", - scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id="octopus", - ) - - -def test_report_errors_service_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( - "google.cloud.errorreporting_v1beta1.services.report_errors_service.transports.ReportErrorsServiceTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ReportErrorsServiceTransport() - adc.assert_called_once() - - -def test_report_errors_service_auth_adc(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - ReportErrorsServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ReportErrorsServiceGrpcTransport, - transports.ReportErrorsServiceGrpcAsyncIOTransport, - ], -) -def test_report_errors_service_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ReportErrorsServiceGrpcTransport, - transports.ReportErrorsServiceGrpcAsyncIOTransport, - transports.ReportErrorsServiceRestTransport, - ], -) -def test_report_errors_service_transport_auth_gdch_credentials(transport_class): - host = "https://language.com" - api_audience_tests = [None, "https://language2.com"] - api_audience_expect = [host, "https://language2.com"] - for t, e in zip(api_audience_tests, api_audience_expect): - with mock.patch.object(google.auth, "default", autospec=True) as adc: - gdch_mock = mock.MagicMock() - type(gdch_mock).with_gdch_audience = mock.PropertyMock( - return_value=gdch_mock - ) - adc.return_value = (gdch_mock, None) - transport_class(host=host, api_audience=t) - gdch_mock.with_gdch_audience.assert_called_once_with(e) - - -@pytest.mark.parametrize( - "transport_class,grpc_helpers", - [ - (transports.ReportErrorsServiceGrpcTransport, grpc_helpers), - (transports.ReportErrorsServiceGrpcAsyncIOTransport, grpc_helpers_async), - ], -) -def test_report_errors_service_transport_create_channel(transport_class, grpc_helpers): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object( - google.auth, "default", autospec=True - ) as adc, mock.patch.object( - grpc_helpers, "create_channel", autospec=True - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - adc.return_value = (creds, None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - - create_channel.assert_called_with( - "clouderrorreporting.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - scopes=["1", "2"], - default_host="clouderrorreporting.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ReportErrorsServiceGrpcTransport, - transports.ReportErrorsServiceGrpcAsyncIOTransport, - ], -) -def test_report_errors_service_grpc_transport_client_cert_source_for_mtls( - transport_class, -): - cred = ga_credentials.AnonymousCredentials() - - # Check ssl_channel_credentials is used if provided. - with mock.patch.object(transport_class, "create_channel") as mock_create_channel: - mock_ssl_channel_creds = mock.Mock() - transport_class( - host="squid.clam.whelk", - credentials=cred, - ssl_channel_credentials=mock_ssl_channel_creds, - ) - mock_create_channel.assert_called_once_with( - "squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_channel_creds, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls - # is used. - with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): - with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: - transport_class( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback, - ) - expected_cert, expected_key = client_cert_source_callback() - mock_ssl_cred.assert_called_once_with( - certificate_chain=expected_cert, private_key=expected_key - ) - - -def test_report_errors_service_http_transport_client_cert_source_for_mtls(): - cred = ga_credentials.AnonymousCredentials() - with mock.patch( - "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" - ) as mock_configure_mtls_channel: - transports.ReportErrorsServiceRestTransport( - credentials=cred, client_cert_source_for_mtls=client_cert_source_callback - ) - mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) - - -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "grpc_asyncio", - "rest", - ], -) -def test_report_errors_service_host_no_port(transport_name): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions( - api_endpoint="clouderrorreporting.googleapis.com" - ), - transport=transport_name, - ) - assert client.transport._host == ( - "clouderrorreporting.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://clouderrorreporting.googleapis.com" - ) - - -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "grpc_asyncio", - "rest", - ], -) -def test_report_errors_service_host_with_port(transport_name): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions( - api_endpoint="clouderrorreporting.googleapis.com:8000" - ), - transport=transport_name, - ) - assert client.transport._host == ( - "clouderrorreporting.googleapis.com:8000" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://clouderrorreporting.googleapis.com:8000" - ) - - -@pytest.mark.parametrize( - "transport_name", - [ - "rest", - ], -) -def test_report_errors_service_client_transport_session_collision(transport_name): - creds1 = ga_credentials.AnonymousCredentials() - creds2 = ga_credentials.AnonymousCredentials() - client1 = ReportErrorsServiceClient( - credentials=creds1, - transport=transport_name, - ) - client2 = ReportErrorsServiceClient( - credentials=creds2, - transport=transport_name, - ) - session1 = client1.transport.report_error_event._session - session2 = client2.transport.report_error_event._session - assert session1 != session2 - - -def test_report_errors_service_grpc_transport_channel(): - channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.ReportErrorsServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -def test_report_errors_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.ReportErrorsServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.filterwarnings("ignore::FutureWarning") -@pytest.mark.parametrize( - "transport_class", - [ - transports.ReportErrorsServiceGrpcTransport, - transports.ReportErrorsServiceGrpcAsyncIOTransport, - ], -) -def test_report_errors_service_transport_channel_mtls_with_client_cert_source( - transport_class, -): - with mock.patch( - "grpc.ssl_channel_credentials", autospec=True - ) as grpc_ssl_channel_cred: - with mock.patch.object( - transport_class, "create_channel" - ) as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = ga_credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - assert transport._ssl_channel_credentials == mock_ssl_cred - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize( - "transport_class", - [ - transports.ReportErrorsServiceGrpcTransport, - transports.ReportErrorsServiceGrpcAsyncIOTransport, - ], -) -def test_report_errors_service_transport_channel_mtls_with_adc(transport_class): - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - with mock.patch.object( - transport_class, "create_channel" - ) as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_common_billing_account_path(): - billing_account = "squid" - expected = "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - actual = ReportErrorsServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "clam", - } - path = ReportErrorsServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = ReportErrorsServiceClient.parse_common_billing_account_path(path) - assert expected == actual - - -def test_common_folder_path(): - folder = "whelk" - expected = "folders/{folder}".format( - folder=folder, - ) - actual = ReportErrorsServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "octopus", - } - path = ReportErrorsServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = ReportErrorsServiceClient.parse_common_folder_path(path) - assert expected == actual - - -def test_common_organization_path(): - organization = "oyster" - expected = "organizations/{organization}".format( - organization=organization, - ) - actual = ReportErrorsServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "nudibranch", - } - path = ReportErrorsServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = ReportErrorsServiceClient.parse_common_organization_path(path) - assert expected == actual - - -def test_common_project_path(): - project = "cuttlefish" - expected = "projects/{project}".format( - project=project, - ) - actual = ReportErrorsServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "mussel", - } - path = ReportErrorsServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = ReportErrorsServiceClient.parse_common_project_path(path) - assert expected == actual - - -def test_common_location_path(): - project = "winkle" - location = "nautilus" - expected = "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - actual = ReportErrorsServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "scallop", - "location": "abalone", - } - path = ReportErrorsServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = ReportErrorsServiceClient.parse_common_location_path(path) - assert expected == actual - - -def test_client_with_default_client_info(): - client_info = gapic_v1.client_info.ClientInfo() - - with mock.patch.object( - transports.ReportErrorsServiceTransport, "_prep_wrapped_messages" - ) as prep: - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object( - transports.ReportErrorsServiceTransport, "_prep_wrapped_messages" - ) as prep: - transport_class = ReportErrorsServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -def test_transport_close_grpc(): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="grpc" - ) - with mock.patch.object( - type(getattr(client.transport, "_grpc_channel")), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -@pytest.mark.asyncio -async def test_transport_close_grpc_asyncio(): - client = ReportErrorsServiceAsyncClient( - credentials=async_anonymous_credentials(), transport="grpc_asyncio" - ) - with mock.patch.object( - type(getattr(client.transport, "_grpc_channel")), "close" - ) as close: - async with client: - close.assert_not_called() - close.assert_called_once() - - -def test_transport_close_rest(): - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - with mock.patch.object( - type(getattr(client.transport, "_session")), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -def test_client_ctx(): - transports = [ - "rest", - "grpc", - ] - for transport in transports: - client = ReportErrorsServiceClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - # Test client calls underlying transport. - with mock.patch.object(type(client.transport), "close") as close: - close.assert_not_called() - with client: - pass - close.assert_called() - - -@pytest.mark.parametrize( - "client_class,transport_class", - [ - (ReportErrorsServiceClient, transports.ReportErrorsServiceGrpcTransport), - ( - ReportErrorsServiceAsyncClient, - transports.ReportErrorsServiceGrpcAsyncIOTransport, - ), - ], -) -def test_api_key_credentials(client_class, transport_class): - with mock.patch.object( - google.auth._default, "get_api_key_credentials", create=True - ) as get_api_key_credentials: - mock_cred = mock.Mock() - get_api_key_credentials.return_value = mock_cred - options = client_options.ClientOptions() - options.api_key = "api_key" - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=mock_cred, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE - ), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) diff --git a/tests/unit/test__gapic.py b/tests/unit/test__gapic.py deleted file mode 100644 index 52e525e3..00000000 --- a/tests/unit/test__gapic.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright 2017 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import unittest - -import mock - - -class Test_make_report_error_api(unittest.TestCase): - @staticmethod - def _call_fut(client): - from google.cloud.error_reporting._gapic import make_report_error_api - - return make_report_error_api(client) - - def test_make_report_error_api(self): - client = mock.Mock( - spec=["project", "_credentials", "_client_info", "_client_options"] - ) - - # Call the function being tested. - patch = mock.patch( - "google.cloud.errorreporting_v1beta1.ReportErrorsServiceClient" - ) - - with patch as patched: - report_error_client = self._call_fut(client) - - # Assert that the final error client has the project in - # the expected location. - self.assertIs(report_error_client._project, client.project) - self.assertIs(report_error_client._gapic_api, patched.return_value) - patched.assert_called_once_with( - credentials=client._credentials, - client_info=client._client_info, - client_options=client._client_options, - ) - - -class Test_ErrorReportingGapicApi(unittest.TestCase): - PROJECT = "PROJECT" - - def _make_one(self, gapic_api, project): - from google.cloud.error_reporting._gapic import _ErrorReportingGapicApi - - return _ErrorReportingGapicApi(gapic_api, project) - - def test_constructor(self): - gapic_api = mock.Mock(spec=[]) - gapic_client_wrapper = self._make_one(gapic_api, self.PROJECT) - - self.assertEqual(gapic_client_wrapper._project, self.PROJECT) - self.assertEqual(gapic_client_wrapper._gapic_api, gapic_api) - - def test_report_error_event(self): - import google.cloud.errorreporting_v1beta1 - - gapic_api = mock.Mock(spec=["report_error_event"]) - gapic_client_wrapper = self._make_one(gapic_api, self.PROJECT) - - error_report = {"message": "The cabs are here."} - gapic_client_wrapper.report_error_event(error_report) - - project_name = f"projects/{self.PROJECT}" - error_pb = google.cloud.errorreporting_v1beta1.ReportedErrorEvent( - message=error_report["message"] - ) - gapic_api.report_error_event.assert_called_once_with( - project_name=project_name, event=error_pb - ) diff --git a/tests/unit/test__logging.py b/tests/unit/test__logging.py deleted file mode 100644 index 433c9192..00000000 --- a/tests/unit/test__logging.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright 2017 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import unittest - -import mock - - -def _make_credentials(): - import google.auth.credentials - - return mock.Mock(spec=google.auth.credentials.Credentials) - - -class Test_ErrorReportingLoggingAPI(unittest.TestCase): - PROJECT = "PROJECT" - - def _make_one(self, project, credentials, **kw): - from google.cloud.error_reporting._logging import _ErrorReportingLoggingAPI - - return _ErrorReportingLoggingAPI(project, credentials, **kw) - - @mock.patch("google.cloud.logging.Client") - def test_ctor_defaults(self, mocked_cls): - credentials = _make_credentials() - - logging_api = self._make_one(self.PROJECT, credentials) - - self.assertIs(logging_api.logging_client, mocked_cls.return_value) - mocked_cls.assert_called_once_with( - project=self.PROJECT, - credentials=credentials, - _http=None, - client_info=None, - client_options=None, - ) - - @mock.patch("google.cloud.logging.Client") - def test_ctor_explicit(self, mocked_cls): - credentials = _make_credentials() - http = mock.Mock() - client_info = mock.Mock() - client_options = mock.Mock() - - logging_api = self._make_one( - self.PROJECT, - credentials, - _http=http, - client_info=client_info, - client_options=client_options, - ) - - self.assertIs(logging_api.logging_client, mocked_cls.return_value) - mocked_cls.assert_called_once_with( - project=self.PROJECT, - credentials=credentials, - _http=http, - client_info=client_info, - client_options=client_options, - ) - - @mock.patch("google.cloud.logging.Client") - def test_report_error_event(self, mocked_cls): - credentials = _make_credentials() - logging_api = self._make_one(self.PROJECT, credentials) - - logger = mock.Mock(spec=["log_struct"]) - logging_api.logging_client.logger.return_value = logger - - # Actually make the API call. - error_report = {"message": "The cabs are here."} - logging_api.report_error_event(error_report) - - # Check the mocks. - logger.log_struct.assert_called_once_with(error_report) diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py deleted file mode 100644 index e53b1545..00000000 --- a/tests/unit/test_client.py +++ /dev/null @@ -1,221 +0,0 @@ -# Copyright 2016 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -import unittest - -import mock - - -def _make_credentials(): - import google.auth.credentials - - return mock.Mock(spec=google.auth.credentials.Credentials) - - -class TestClient(unittest.TestCase): - PROJECT = "PROJECT" - SERVICE = "SERVICE" - VERSION = "myversion" - - @staticmethod - def _get_target_class(): - from google.cloud.error_reporting.client import Client - - return Client - - def _make_one(self, *args, **kw): - return self._get_target_class()(*args, **kw) - - def _make_http(self, *args, **kw): - from google.cloud.error_reporting.client import HTTPContext - - return HTTPContext(*args, **kw) - - def _get_report_payload(self, error_api): - self.assertEqual(error_api.report_error_event.call_count, 1) - call = error_api.report_error_event.mock_calls[0] - _, positional, kwargs = call - self.assertEqual(kwargs, {}) - self.assertEqual(len(positional), 1) - return positional[0] - - @mock.patch("google.cloud.client._determine_default_project") - def test_ctor_defaults(self, default_mock): - from google.api_core.client_info import ClientInfo - - credentials = _make_credentials() - default_mock.return_value = "foo" - client = self._make_one(credentials=credentials) - self.assertEqual(client.service, client.DEFAULT_SERVICE) - self.assertEqual(client.version, None) - self.assertIsInstance(client._client_info, ClientInfo) - default_mock.assert_called_once_with(None) - - def test_ctor_explicit(self): - credentials = _make_credentials() - client_info = mock.Mock() - client_options = mock.Mock() - client = self._make_one( - project=self.PROJECT, - credentials=credentials, - service=self.SERVICE, - version=self.VERSION, - client_info=client_info, - client_options=client_options, - ) - self.assertEqual(client.service, self.SERVICE) - self.assertEqual(client.version, self.VERSION) - self.assertIs(client._client_info, client_info) - self.assertIs(client._client_options, client_options) - - def test_report_errors_api_already(self): - credentials = _make_credentials() - client = self._make_one(project=self.PROJECT, credentials=credentials) - client._report_errors_api = already = mock.Mock() - self.assertIs(client.report_errors_api, already) - - def test_report_errors_api_wo_grpc(self): - credentials = _make_credentials() - client_info = mock.Mock() - client_options = mock.Mock() - http = mock.Mock() - client = self._make_one( - project=self.PROJECT, - credentials=credentials, - client_info=client_info, - client_options=client_options, - _http=http, - _use_grpc=False, - ) - patch = mock.patch( - "google.cloud.error_reporting.client._ErrorReportingLoggingAPI" - ) - - with patch as patched: - api = client.report_errors_api - - self.assertIs(api, patched.return_value) - patched.assert_called_once_with( - self.PROJECT, credentials, http, client_info, client_options - ) - - def test_report_errors_api_w_grpc(self): - credentials = _make_credentials() - client = self._make_one( - project=self.PROJECT, credentials=credentials, _use_grpc=True - ) - patch = mock.patch("google.cloud.error_reporting.client.make_report_error_api") - - with patch as patched: - api = client.report_errors_api - - self.assertIs(api, patched.return_value) - patched.assert_called_once_with(client) - - def test_report_exception_with_grpc(self): - credentials = _make_credentials() - client = self._make_one(project=self.PROJECT, credentials=credentials) - - patch = mock.patch("google.cloud.error_reporting.client.make_report_error_api") - with patch as make_api: - try: - raise NameError - except NameError: - client.report_exception() - payload = make_api.return_value.report_error_event.call_args[0][0] - make_api.assert_called_once_with(client) - - self.assertEqual(payload["serviceContext"], {"service": client.DEFAULT_SERVICE}) - self.assertIn("test_report", payload["message"]) - self.assertIn("test_client.py", payload["message"]) - - def test_report_exception_wo_grpc(self): - credentials = _make_credentials() - client = self._make_one( - project=self.PROJECT, credentials=credentials, _use_grpc=False - ) - patch = mock.patch( - "google.cloud.error_reporting.client._ErrorReportingLoggingAPI" - ) - with patch as _error_api: - try: - raise NameError - except NameError: - client.report_exception() - mock_report = _error_api.return_value.report_error_event - payload = mock_report.call_args[0][0] - - self.assertEqual(payload["serviceContext"], {"service": client.DEFAULT_SERVICE}) - self.assertIn("test_report", payload["message"]) - self.assertIn("test_client.py", payload["message"]) - self.assertIsNotNone(client.report_errors_api) - - @mock.patch("google.cloud.error_reporting.client.make_report_error_api") - def test_report_exception_with_service_version_in_constructor(self, make_api): - credentials = _make_credentials() - service = "notdefault" - version = "notdefaultversion" - client = self._make_one( - project=self.PROJECT, - credentials=credentials, - service=service, - version=version, - ) - - http_context = self._make_http(method="GET", response_status_code=500) - user = "user@gmail.com" - - error_api = mock.Mock(spec=["report_error_event"]) - make_api.return_value = error_api - - try: - raise NameError - except NameError: - client.report_exception(http_context=http_context, user=user) - - make_api.assert_called_once_with(client) - - payload = self._get_report_payload(error_api) - self.assertEqual( - payload["serviceContext"], {"service": service, "version": version} - ) - self.assertIn( - "test_report_exception_with_service_version_in_constructor", - payload["message"], - ) - self.assertIn("test_client.py", payload["message"]) - self.assertEqual(payload["context"]["httpRequest"]["responseStatusCode"], 500) - self.assertEqual(payload["context"]["httpRequest"]["method"], "GET") - self.assertEqual(payload["context"]["user"], user) - - @mock.patch("google.cloud.error_reporting.client.make_report_error_api") - def test_report(self, make_api): - credentials = _make_credentials() - client = self._make_one(project=self.PROJECT, credentials=credentials) - - error_api = mock.Mock(spec=["report_error_event"]) - make_api.return_value = error_api - - message = "this is an error" - client.report(message) - - payload = self._get_report_payload(error_api) - - self.assertEqual(payload["message"], message) - report_location = payload["context"]["reportLocation"] - self.assertIn("test_client.py", report_location["filePath"]) - self.assertEqual(report_location["functionName"], "test_report") - self.assertGreater(report_location["lineNumber"], 100) - self.assertLess(report_location["lineNumber"], 250) diff --git a/tests/unit/test_packaging.py b/tests/unit/test_packaging.py deleted file mode 100644 index 01ab6a79..00000000 --- a/tests/unit/test_packaging.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import subprocess -import sys - - -def test_namespace_package_compat(tmp_path): - # The ``google`` namespace package should not be masked - # by the presence of ``google-cloud-error-reporting``. - - google = tmp_path / "google" - google.mkdir() - google.joinpath("othermod.py").write_text("") - - google_otherpkg = tmp_path / "google" / "otherpkg" - google_otherpkg.mkdir() - google_otherpkg.joinpath("__init__.py").write_text("") - - # The ``google.cloud`` namespace package should not be masked - # by the presence of ``google-cloud-error-reporting``. - google_cloud = tmp_path / "google" / "cloud" - google_cloud.mkdir() - google_cloud.joinpath("othermod.py").write_text("") - - google_cloud_otherpkg = tmp_path / "google" / "cloud" / "otherpkg" - google_cloud_otherpkg.mkdir() - google_cloud_otherpkg.joinpath("__init__.py").write_text("") - - env = dict(os.environ, PYTHONPATH=str(tmp_path)) - - for pkg in [ - "google.othermod", - "google.cloud.othermod", - "google.otherpkg", - "google.cloud.otherpkg", - "google.cloud.error_reporting", - "google.cloud.errorreporting_v1beta1", - ]: - cmd = [sys.executable, "-c", f"import {pkg}"] - subprocess.check_output(cmd, env=env) - - for module in ["google.othermod", "google.cloud.othermod"]: - cmd = [sys.executable, "-m", module] - subprocess.check_output(cmd, env=env) diff --git a/tests/unit/test_util.py b/tests/unit/test_util.py deleted file mode 100644 index cd48f3f8..00000000 --- a/tests/unit/test_util.py +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2016 Google LLC All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import unittest - - -class Test_build_flask_context(unittest.TestCase): - def _call_fut(self, request): - from google.cloud.error_reporting.util import build_flask_context - - return build_flask_context(request) - - def test_flask_helper(self): - import mock - - user_agent = mock.Mock(string="Google Cloud Unit Tests Agent") - request = _Request( - "http://google.com", "GET", user_agent, "http://gmail.com", "127.0.0.1" - ) - - context = self._call_fut(request) - self.assertEqual(request.url, context.url) - self.assertEqual(request.method, context.method) - self.assertEqual(request.user_agent.string, context.userAgent) - self.assertEqual(request.referrer, context.referrer) - self.assertEqual(request.remote_addr, context.remoteIp) - - -class _Request(object): - def __init__(self, url, method, user_agent, referrer, remote_addr): - self.url = url - self.method = method - self.user_agent = user_agent - self.referrer = referrer - self.remote_addr = remote_addr