diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 9ee60f7e4..cb89b2e32 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,3 +1,3 @@ docker: - image: gcr.io/repo-automation-bots/owlbot-python:latest - digest: sha256:aea14a583128771ae8aefa364e1652f3c56070168ef31beb203534222d842b8b + image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest + digest: sha256:ec49167c606648a063d1222220b48119c912562849a0528f35bfb592a9f72737 diff --git a/.github/.OwlBot.yaml b/.github/.OwlBot.yaml index 63a2aab54..58377caf6 100644 --- a/.github/.OwlBot.yaml +++ b/.github/.OwlBot.yaml @@ -13,7 +13,7 @@ # limitations under the License. docker: - image: gcr.io/repo-automation-bots/owlbot-python:latest + image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest deep-remove-regex: - /owl-bot-staging diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index af5993532..3e98ae70f 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -1,9 +1,11 @@ -# https://github.com/googleapis/repo-automation-bots/tree/master/packages/sync-repo-settings -# Rules for master branch protection +# 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 `master` -- pattern: master +# Defaults to `main` +- pattern: main + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: true requiredStatusCheckContexts: - 'Kokoro' - 'cla/google' diff --git a/.kokoro/build.sh b/.kokoro/build.sh index cb17176f0..4d739a338 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -41,7 +41,7 @@ python3 -m pip install --upgrade --quiet nox python3 -m nox --version # If this is a continuous build, send the test log to the FlakyBot. -# See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. +# 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 diff --git a/.kokoro/docs/common.cfg b/.kokoro/docs/common.cfg index 7bb6536d7..4e013a7f7 100644 --- a/.kokoro/docs/common.cfg +++ b/.kokoro/docs/common.cfg @@ -30,6 +30,7 @@ env_vars: { env_vars: { key: "V2_STAGING_BUCKET" + # Push google cloud library docs to the Cloud RAD bucket `docs-staging-v2` value: "docs-staging-v2" } diff --git a/.kokoro/environment_tests.sh b/.kokoro/environment_tests.sh index f8f138ea1..2b6fa5177 100755 --- a/.kokoro/environment_tests.sh +++ b/.kokoro/environment_tests.sh @@ -72,6 +72,7 @@ echo $ENVCTL_ID # Run the specified environment test set +e + python3.6 -m nox --session "tests(language='python', platform='$ENVIRONMENT')" TEST_STATUS_CODE=$? diff --git a/.kokoro/samples/lint/common.cfg b/.kokoro/samples/lint/common.cfg index ceb20370e..9123caa63 100644 --- a/.kokoro/samples/lint/common.cfg +++ b/.kokoro/samples/lint/common.cfg @@ -31,4 +31,4 @@ gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" # Use the trampoline script to run in docker. -build_file: "python-logging/.kokoro/trampoline.sh" \ No newline at end of file +build_file: "python-logging/.kokoro/trampoline_v2.sh" \ No newline at end of file diff --git a/.kokoro/samples/python3.10/common.cfg b/.kokoro/samples/python3.10/common.cfg new file mode 100644 index 000000000..61142a001 --- /dev/null +++ b/.kokoro/samples/python3.10/common.cfg @@ -0,0 +1,40 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "py-3.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-logging/.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-logging/.kokoro/trampoline_v2.sh" \ No newline at end of file diff --git a/.kokoro/samples/python3.10/continuous.cfg b/.kokoro/samples/python3.10/continuous.cfg new file mode 100644 index 000000000..a1c8d9759 --- /dev/null +++ b/.kokoro/samples/python3.10/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.10/periodic-head.cfg b/.kokoro/samples/python3.10/periodic-head.cfg new file mode 100644 index 000000000..7e2973e3b --- /dev/null +++ b/.kokoro/samples/python3.10/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-logging/.kokoro/test-samples-against-head.sh" +} diff --git a/.kokoro/samples/python3.10/periodic.cfg b/.kokoro/samples/python3.10/periodic.cfg new file mode 100644 index 000000000..71cd1e597 --- /dev/null +++ b/.kokoro/samples/python3.10/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.10/presubmit.cfg b/.kokoro/samples/python3.10/presubmit.cfg new file mode 100644 index 000000000..a1c8d9759 --- /dev/null +++ b/.kokoro/samples/python3.10/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/.kokoro/samples/python3.6/common.cfg b/.kokoro/samples/python3.6/common.cfg index 1bfa98c11..792a4d14c 100644 --- a/.kokoro/samples/python3.6/common.cfg +++ b/.kokoro/samples/python3.6/common.cfg @@ -37,4 +37,4 @@ gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" # Use the trampoline script to run in docker. -build_file: "python-logging/.kokoro/trampoline.sh" \ No newline at end of file +build_file: "python-logging/.kokoro/trampoline_v2.sh" \ No newline at end of file diff --git a/.kokoro/samples/python3.6/periodic.cfg b/.kokoro/samples/python3.6/periodic.cfg index 50fec9649..71cd1e597 100644 --- a/.kokoro/samples/python3.6/periodic.cfg +++ b/.kokoro/samples/python3.6/periodic.cfg @@ -3,4 +3,4 @@ env_vars: { key: "INSTALL_LIBRARY_FROM_SOURCE" value: "False" -} \ No newline at end of file +} diff --git a/.kokoro/samples/python3.7/common.cfg b/.kokoro/samples/python3.7/common.cfg index 0f8e2c95d..3ba076fea 100644 --- a/.kokoro/samples/python3.7/common.cfg +++ b/.kokoro/samples/python3.7/common.cfg @@ -37,4 +37,4 @@ gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" # Use the trampoline script to run in docker. -build_file: "python-logging/.kokoro/trampoline.sh" \ No newline at end of file +build_file: "python-logging/.kokoro/trampoline_v2.sh" \ No newline at end of file diff --git a/.kokoro/samples/python3.7/periodic.cfg b/.kokoro/samples/python3.7/periodic.cfg index 50fec9649..71cd1e597 100644 --- a/.kokoro/samples/python3.7/periodic.cfg +++ b/.kokoro/samples/python3.7/periodic.cfg @@ -3,4 +3,4 @@ env_vars: { key: "INSTALL_LIBRARY_FROM_SOURCE" value: "False" -} \ No newline at end of file +} diff --git a/.kokoro/samples/python3.8/common.cfg b/.kokoro/samples/python3.8/common.cfg index 6c1d661d2..144751654 100644 --- a/.kokoro/samples/python3.8/common.cfg +++ b/.kokoro/samples/python3.8/common.cfg @@ -37,4 +37,4 @@ gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" # Use the trampoline script to run in docker. -build_file: "python-logging/.kokoro/trampoline.sh" \ No newline at end of file +build_file: "python-logging/.kokoro/trampoline_v2.sh" \ No newline at end of file diff --git a/.kokoro/samples/python3.8/periodic.cfg b/.kokoro/samples/python3.8/periodic.cfg index 50fec9649..71cd1e597 100644 --- a/.kokoro/samples/python3.8/periodic.cfg +++ b/.kokoro/samples/python3.8/periodic.cfg @@ -3,4 +3,4 @@ env_vars: { key: "INSTALL_LIBRARY_FROM_SOURCE" value: "False" -} \ No newline at end of file +} diff --git a/.kokoro/samples/python3.9/common.cfg b/.kokoro/samples/python3.9/common.cfg index d4c521347..f6f6943a5 100644 --- a/.kokoro/samples/python3.9/common.cfg +++ b/.kokoro/samples/python3.9/common.cfg @@ -37,4 +37,4 @@ gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" # Use the trampoline script to run in docker. -build_file: "python-logging/.kokoro/trampoline.sh" \ No newline at end of file +build_file: "python-logging/.kokoro/trampoline_v2.sh" \ No newline at end of file diff --git a/.kokoro/samples/python3.9/periodic.cfg b/.kokoro/samples/python3.9/periodic.cfg index 50fec9649..71cd1e597 100644 --- a/.kokoro/samples/python3.9/periodic.cfg +++ b/.kokoro/samples/python3.9/periodic.cfg @@ -3,4 +3,4 @@ env_vars: { key: "INSTALL_LIBRARY_FROM_SOURCE" value: "False" -} \ No newline at end of file +} diff --git a/.kokoro/test-samples-against-head.sh b/.kokoro/test-samples-against-head.sh index 635a5ace0..ba3a707b0 100755 --- a/.kokoro/test-samples-against-head.sh +++ b/.kokoro/test-samples-against-head.sh @@ -23,6 +23,4 @@ set -eo pipefail # Enables `**` to include files nested inside sub-folders shopt -s globstar -cd github/python-logging - exec .kokoro/test-samples-impl.sh diff --git a/.kokoro/test-samples-impl.sh b/.kokoro/test-samples-impl.sh index 311a8d54b..8a324c9c7 100755 --- a/.kokoro/test-samples-impl.sh +++ b/.kokoro/test-samples-impl.sh @@ -80,7 +80,7 @@ for file in samples/**/requirements.txt; do EXIT=$? # If this is a periodic build, send the test log to the FlakyBot. - # See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. + # 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 diff --git a/.kokoro/test-samples.sh b/.kokoro/test-samples.sh index 0f5f8d400..11c042d34 100755 --- a/.kokoro/test-samples.sh +++ b/.kokoro/test-samples.sh @@ -24,8 +24,6 @@ set -eo pipefail # Enables `**` to include files nested inside sub-folders shopt -s globstar -cd github/python-logging - # Run periodic samples tests at latest release if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then # preserving the test runner implementation. diff --git a/.repo-metadata.json b/.repo-metadata.json index 911d58dca..fdb0a66c2 100644 --- a/.repo-metadata.json +++ b/.repo-metadata.json @@ -1,14 +1,15 @@ { - "name": "logging", - "name_pretty": "Cloud Logging", - "product_documentation": "https://cloud.google.com/logging/docs", - "client_documentation": "https://googleapis.dev/python/logging/latest", - "issue_tracker": "https://issuetracker.google.com/savedsearches/559764", - "release_level": "ga", - "language": "python", - "library_type": "GAPIC_COMBO", - "repo": "googleapis/python-logging", - "distribution_name": "google-cloud-logging", - "api_id": "logging.googleapis.com", - "codeowner_team": "@googleapis/api-logging" -} \ No newline at end of file + "name": "logging", + "name_pretty": "Cloud Logging", + "product_documentation": "https://cloud.google.com/logging/docs", + "client_documentation": "https://googleapis.dev/python/logging/latest", + "issue_tracker": "https://issuetracker.google.com/savedsearches/559764", + "release_level": "ga", + "language": "python", + "library_type": "GAPIC_COMBO", + "repo": "googleapis/python-logging", + "distribution_name": "google-cloud-logging", + "api_id": "logging.googleapis.com", + "codeowner_team": "@googleapis/api-logging", + "default_version": "v2" +} diff --git a/.trampolinerc b/.trampolinerc index 6f984309b..a51abf0b5 100644 --- a/.trampolinerc +++ b/.trampolinerc @@ -21,9 +21,22 @@ required_envvars+=() pass_down_envvars+=( "ENVIRONMENT" "RUNTIME" + "NOX_SESSION" + ############### + # Docs builds + ############### "STAGING_BUCKET" "V2_STAGING_BUCKET" - "NOX_SESSION" + ################## + # 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. diff --git a/CHANGELOG.md b/CHANGELOG.md index 450c1486c..068ad3df2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,32 @@ [1]: https://pypi.org/project/google-cloud-logging/#history +## [2.7.0](https://www.github.com/googleapis/python-logging/compare/v2.6.0...v2.7.0) (2021-11-02) + + +### Features + +* add context manager support in client ([#415](https://www.github.com/googleapis/python-logging/issues/415)) ([f5af164](https://www.github.com/googleapis/python-logging/commit/f5af16439807a0954ee78fa91cb69b9493b80176)) +* added support for iam AuditData proto ([#396](https://www.github.com/googleapis/python-logging/issues/396)) ([e3a1eba](https://www.github.com/googleapis/python-logging/commit/e3a1eba74dd8b67bcc73a78f784189ef2a9927c2)) +* use structured logging on GCF with python 3.7 ([#434](https://www.github.com/googleapis/python-logging/issues/434)) ([5055919](https://www.github.com/googleapis/python-logging/commit/5055919f70c82b38de6d1fa7f1df6006865a857b)) + + +### Bug Fixes + +* add 'dict' annotation type to 'request' ([76ac729](https://www.github.com/googleapis/python-logging/commit/76ac729e42a782524be87ad71745aad37bbe1653)) +* add 'dict' annotation type to 'request' ([23f9e1f](https://www.github.com/googleapis/python-logging/commit/23f9e1f6e9af30c4e65578edbf73c8c893b35285)) +* **deps:** drop packaging dependency ([9d38995](https://www.github.com/googleapis/python-logging/commit/9d389958c7de31ae9e21228eaf965762b31d5e48)) +* **deps:** require google-api-core >= 1.28.0 ([9d38995](https://www.github.com/googleapis/python-logging/commit/9d389958c7de31ae9e21228eaf965762b31d5e48)) +* **deps:** require proto-plus==1.15.0 ([76ac729](https://www.github.com/googleapis/python-logging/commit/76ac729e42a782524be87ad71745aad37bbe1653)) +* exception log message format ([#394](https://www.github.com/googleapis/python-logging/issues/394)) ([c426bf5](https://www.github.com/googleapis/python-logging/commit/c426bf56787fa02140e8aa142ecd4d4e45432697)) +* improper types in pagers generation ([76ac729](https://www.github.com/googleapis/python-logging/commit/76ac729e42a782524be87ad71745aad37bbe1653)) +* improper types in pagers generation ([6a837a5](https://www.github.com/googleapis/python-logging/commit/6a837a5d1faab1f9fa8ac94e424e847821a0069f)) + + +### Documentation + +* list oneofs in docstring ([9d38995](https://www.github.com/googleapis/python-logging/commit/9d389958c7de31ae9e21228eaf965762b31d5e48)) + ## [2.6.0](https://www.github.com/googleapis/python-logging/compare/v2.5.0...v2.6.0) (2021-07-28) @@ -150,7 +176,7 @@ ### ⚠ BREAKING CHANGES -* Use microgenerator for GAPIC layer. See [UPGRADING.md](https://github.com/googleapis/python-logging/blob/master/UPGRADING.md) for details. (#94) +* Use microgenerator for GAPIC layer. See [UPGRADING.md](https://github.com/googleapis/python-logging/blob/main/UPGRADING.md) for details. (#94) * removes support for webapp2 and other Python2 specific code ### Features diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index f5505c222..1839c49a7 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.6, 3.7, 3.8 and 3.9 on both UNIX and Windows. + 3.6, 3.7, 3.8, 3.9 and 3.10 on both UNIX and Windows. - The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should @@ -50,9 +50,9 @@ You'll have to create a development environment using a Git checkout: # Configure remotes such that you can pull changes from the googleapis/python-logging # repository into your local repository. $ git remote add upstream git@github.com:googleapis/python-logging.git - # fetch and merge changes from upstream into master + # fetch and merge changes from upstream into main $ git fetch upstream - $ git merge upstream/master + $ 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. @@ -72,7 +72,7 @@ We use `nox `__ to instrument our tests. - To run a single unit test:: - $ nox -s unit-3.9 -- -k + $ nox -s unit-3.10 -- -k .. note:: @@ -110,12 +110,12 @@ Coding Style variables:: export GOOGLE_CLOUD_TESTING_REMOTE="upstream" - export GOOGLE_CLOUD_TESTING_BRANCH="master" + export GOOGLE_CLOUD_TESTING_BRANCH="main" By doing this, you are specifying the location of the most up-to-date - version of ``python-logging``. The the suggested remote name ``upstream`` - should point to the official ``googleapis`` checkout and the - the branch should be the main branch on that remote (``master``). + version of ``python-logging``. 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 @@ -209,7 +209,7 @@ 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-logging/blob/master/CONTRIBUTING.rst``) +``https://github.com/googleapis/python-logging/blob/main/CONTRIBUTING.rst``) may cause problems creating links or rendering the description. .. _description on PyPI: https://pypi.org/project/google-cloud-logging @@ -225,16 +225,18 @@ We support: - `Python 3.7`_ - `Python 3.8`_ - `Python 3.9`_ +- `Python 3.10`_ .. _Python 3.6: https://docs.python.org/3.6/ .. _Python 3.7: https://docs.python.org/3.7/ .. _Python 3.8: https://docs.python.org/3.8/ .. _Python 3.9: https://docs.python.org/3.9/ +.. _Python 3.10: https://docs.python.org/3.10/ Supported versions can be found in our ``noxfile.py`` `config`_. -.. _config: https://github.com/googleapis/python-logging/blob/master/noxfile.py +.. _config: https://github.com/googleapis/python-logging/blob/main/noxfile.py We also explicitly decided to support Python 3 beginning with version 3.6. diff --git a/docs/conf.py b/docs/conf.py index 6e52e94f3..743981d3a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -76,8 +76,8 @@ # The encoding of source files. # source_encoding = 'utf-8-sig' -# The master toctree document. -master_doc = "index" +# The root toctree document. +root_doc = "index" # General information about the project. project = "google-cloud-logging" @@ -110,6 +110,7 @@ # directories to ignore when looking for source files. exclude_patterns = [ "_build", + "**/.nox/**/*", "samples/AUTHORING_GUIDE.md", "samples/CONTRIBUTING.md", "samples/snippets/README.rst", @@ -279,7 +280,7 @@ # author, documentclass [howto, manual, or own class]). latex_documents = [ ( - master_doc, + root_doc, "google-cloud-logging.tex", "google-cloud-logging Documentation", author, @@ -314,7 +315,7 @@ # (source start file, name, description, authors, manual section). man_pages = [ ( - master_doc, + root_doc, "google-cloud-logging", "google-cloud-logging Documentation", [author], @@ -333,7 +334,7 @@ # dir menu entry, description, category) texinfo_documents = [ ( - master_doc, + root_doc, "google-cloud-logging", "google-cloud-logging Documentation", author, diff --git a/docs/usage.rst b/docs/usage.rst index 1ea9440fc..1fde3d8ea 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -84,6 +84,15 @@ Retrieve entries for a single logger, sorting in descending timestamp order: :end-before: [END logger_list_entries] :dedent: 4 +And as a practical example, retrieve all `GKE Admin Activity audit logs`_ +from the past 24 hours: + +.. _GKE Admin Activity audit logs: https://cloud.google.com/kubernetes-engine/docs/how-to/audit-logging#audit_logs_in_your_project + +.. literalinclude:: ../samples/snippets/usage_guide.py + :start-after: [START logging_list_gke_audit_logs] + :end-before: [END logging_list_gke_audit_logs] + :dedent: 4 Delete all entries for a logger ------------------------------- diff --git a/google/cloud/logging_v2/client.py b/google/cloud/logging_v2/client.py index 51d93355c..e9b432eb2 100644 --- a/google/cloud/logging_v2/client.py +++ b/google/cloud/logging_v2/client.py @@ -355,13 +355,9 @@ def get_default_handler(self, **kw): return AppEngineHandler(self, **kw) elif monitored_resource.type == _GKE_RESOURCE_TYPE: return ContainerEngineHandler(**kw) - elif ( - monitored_resource.type == _GCF_RESOURCE_TYPE - and sys.version_info[0] == 3 - and sys.version_info[1] >= 8 - ): - # Cloud Functions with runtimes > 3.8 supports structured logs on standard out - # 3.7 should use the standard CloudLoggingHandler, which sends logs over the network. + elif monitored_resource.type == _GCF_RESOURCE_TYPE: + # __stdout__ stream required to support structured logging on Python 3.7 + kw["stream"] = kw.get("stream", sys.__stdout__) return StructuredLogHandler(**kw, project_id=self.project) elif monitored_resource.type == _RUN_RESOURCE_TYPE: return StructuredLogHandler(**kw, project_id=self.project) diff --git a/google/cloud/logging_v2/entries.py b/google/cloud/logging_v2/entries.py index fa7e5d9d1..0af5a46f7 100644 --- a/google/cloud/logging_v2/entries.py +++ b/google/cloud/logging_v2/entries.py @@ -30,6 +30,7 @@ # import officially supported proto definitions import google.cloud.audit.audit_log_pb2 # noqa: F401 import google.cloud.appengine_logging # noqa: F401 +from google.iam.v1.logging import audit_data_pb2 # noqa: F401 _GLOBAL_RESOURCE = Resource(type="global", labels={}) diff --git a/google/cloud/logging_v2/handlers/structured_log.py b/google/cloud/logging_v2/handlers/structured_log.py index f0b4c69ec..43e1250a3 100644 --- a/google/cloud/logging_v2/handlers/structured_log.py +++ b/google/cloud/logging_v2/handlers/structured_log.py @@ -62,9 +62,14 @@ def format(self, record): # let other formatters alter the message super_payload = None if record.msg: + # format the message using default handler behaviors super_payload = super(StructuredLogHandler, self).format(record) # properly break any formatting in string to make it json safe record._formatted_msg = json.dumps(super_payload or "") + # remove exception info to avoid duplicating it + # https://github.com/googleapis/python-logging/issues/382 + record.exc_info = None + record.exc_text = None # convert to GCP structred logging format gcp_payload = self._gcp_formatter.format(record) return gcp_payload diff --git a/google/cloud/logging_v2/handlers/transports/background_thread.py b/google/cloud/logging_v2/handlers/transports/background_thread.py index 3d654dbd8..60828a117 100644 --- a/google/cloud/logging_v2/handlers/transports/background_thread.py +++ b/google/cloud/logging_v2/handlers/transports/background_thread.py @@ -22,12 +22,11 @@ import atexit import datetime import logging +import queue import sys import threading import time -from six.moves import queue - from google.cloud.logging_v2 import _helpers from google.cloud.logging_v2.handlers.transports.base import Transport diff --git a/google/cloud/logging_v2/services/config_service_v2/async_client.py b/google/cloud/logging_v2/services/config_service_v2/async_client.py index 634c106b6..23db3b5c1 100644 --- a/google/cloud/logging_v2/services/config_service_v2/async_client.py +++ b/google/cloud/logging_v2/services/config_service_v2/async_client.py @@ -19,13 +19,15 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore +from google.api_core.client_options import ClientOptions # type: ignore from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore +OptionalRetry = Union[retries.Retry, object] + from google.cloud.logging_v2.services.config_service_v2 import pagers from google.cloud.logging_v2.types import logging_config from google.protobuf import field_mask_pb2 # type: ignore @@ -177,17 +179,17 @@ def __init__( async def list_buckets( self, - request: logging_config.ListBucketsRequest = None, + request: Union[logging_config.ListBucketsRequest, dict] = None, *, parent: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListBucketsAsyncPager: r"""Lists buckets. Args: - request (:class:`google.cloud.logging_v2.types.ListBucketsRequest`): + request (Union[google.cloud.logging_v2.types.ListBucketsRequest, dict]): The request object. The parameters to `ListBuckets`. parent (:class:`str`): Required. The parent resource whose buckets are to be @@ -266,16 +268,16 @@ async def list_buckets( async def get_bucket( self, - request: logging_config.GetBucketRequest = None, + request: Union[logging_config.GetBucketRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogBucket: r"""Gets a bucket. Args: - request (:class:`google.cloud.logging_v2.types.GetBucketRequest`): + request (Union[google.cloud.logging_v2.types.GetBucketRequest, dict]): The request object. The parameters to `GetBucket`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -312,9 +314,9 @@ async def get_bucket( async def create_bucket( self, - request: logging_config.CreateBucketRequest = None, + request: Union[logging_config.CreateBucketRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogBucket: @@ -323,7 +325,7 @@ async def create_bucket( cannot be changed. Args: - request (:class:`google.cloud.logging_v2.types.CreateBucketRequest`): + request (Union[google.cloud.logging_v2.types.CreateBucketRequest, dict]): The request object. The parameters to `CreateBucket`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -360,9 +362,9 @@ async def create_bucket( async def update_bucket( self, - request: logging_config.UpdateBucketRequest = None, + request: Union[logging_config.UpdateBucketRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogBucket: @@ -379,7 +381,7 @@ async def update_bucket( A buckets region may not be modified after it is created. Args: - request (:class:`google.cloud.logging_v2.types.UpdateBucketRequest`): + request (Union[google.cloud.logging_v2.types.UpdateBucketRequest, dict]): The request object. The parameters to `UpdateBucket`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -416,9 +418,9 @@ async def update_bucket( async def delete_bucket( self, - request: logging_config.DeleteBucketRequest = None, + request: Union[logging_config.DeleteBucketRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: @@ -427,7 +429,7 @@ async def delete_bucket( the bucket will be permanently deleted. Args: - request (:class:`google.cloud.logging_v2.types.DeleteBucketRequest`): + request (Union[google.cloud.logging_v2.types.DeleteBucketRequest, dict]): The request object. The parameters to `DeleteBucket`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -459,9 +461,9 @@ async def delete_bucket( async def undelete_bucket( self, - request: logging_config.UndeleteBucketRequest = None, + request: Union[logging_config.UndeleteBucketRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: @@ -469,7 +471,7 @@ async def undelete_bucket( may be undeleted within the grace period of 7 days. Args: - request (:class:`google.cloud.logging_v2.types.UndeleteBucketRequest`): + request (Union[google.cloud.logging_v2.types.UndeleteBucketRequest, dict]): The request object. The parameters to `UndeleteBucket`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -501,17 +503,17 @@ async def undelete_bucket( async def list_views( self, - request: logging_config.ListViewsRequest = None, + request: Union[logging_config.ListViewsRequest, dict] = None, *, parent: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListViewsAsyncPager: r"""Lists views on a bucket. Args: - request (:class:`google.cloud.logging_v2.types.ListViewsRequest`): + request (Union[google.cloud.logging_v2.types.ListViewsRequest, dict]): The request object. The parameters to `ListViews`. parent (:class:`str`): Required. The bucket whose views are to be listed: @@ -582,16 +584,16 @@ async def list_views( async def get_view( self, - request: logging_config.GetViewRequest = None, + request: Union[logging_config.GetViewRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogView: r"""Gets a view. Args: - request (:class:`google.cloud.logging_v2.types.GetViewRequest`): + request (Union[google.cloud.logging_v2.types.GetViewRequest, dict]): The request object. The parameters to `GetView`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -630,9 +632,9 @@ async def get_view( async def create_view( self, - request: logging_config.CreateViewRequest = None, + request: Union[logging_config.CreateViewRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogView: @@ -640,7 +642,7 @@ async def create_view( contain a maximum of 50 views. Args: - request (:class:`google.cloud.logging_v2.types.CreateViewRequest`): + request (Union[google.cloud.logging_v2.types.CreateViewRequest, dict]): The request object. The parameters to `CreateView`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -679,9 +681,9 @@ async def create_view( async def update_view( self, - request: logging_config.UpdateViewRequest = None, + request: Union[logging_config.UpdateViewRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogView: @@ -689,7 +691,7 @@ async def update_view( existing view with values from the new view: ``filter``. Args: - request (:class:`google.cloud.logging_v2.types.UpdateViewRequest`): + request (Union[google.cloud.logging_v2.types.UpdateViewRequest, dict]): The request object. The parameters to `UpdateView`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -728,16 +730,16 @@ async def update_view( async def delete_view( self, - request: logging_config.DeleteViewRequest = None, + request: Union[logging_config.DeleteViewRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: r"""Deletes a view from a bucket. Args: - request (:class:`google.cloud.logging_v2.types.DeleteViewRequest`): + request (Union[google.cloud.logging_v2.types.DeleteViewRequest, dict]): The request object. The parameters to `DeleteView`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -769,17 +771,17 @@ async def delete_view( async def list_sinks( self, - request: logging_config.ListSinksRequest = None, + request: Union[logging_config.ListSinksRequest, dict] = None, *, parent: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListSinksAsyncPager: r"""Lists sinks. Args: - request (:class:`google.cloud.logging_v2.types.ListSinksRequest`): + request (Union[google.cloud.logging_v2.types.ListSinksRequest, dict]): The request object. The parameters to `ListSinks`. parent (:class:`str`): Required. The parent resource whose sinks are to be @@ -865,17 +867,17 @@ async def list_sinks( async def get_sink( self, - request: logging_config.GetSinkRequest = None, + request: Union[logging_config.GetSinkRequest, dict] = None, *, sink_name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogSink: r"""Gets a sink. Args: - request (:class:`google.cloud.logging_v2.types.GetSinkRequest`): + request (Union[google.cloud.logging_v2.types.GetSinkRequest, dict]): The request object. The parameters to `GetSink`. sink_name (:class:`str`): Required. The resource name of the sink: @@ -963,11 +965,11 @@ async def get_sink( async def create_sink( self, - request: logging_config.CreateSinkRequest = None, + request: Union[logging_config.CreateSinkRequest, dict] = None, *, parent: str = None, sink: logging_config.LogSink = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogSink: @@ -978,7 +980,7 @@ async def create_sink( entries only from the resource owning the sink. Args: - request (:class:`google.cloud.logging_v2.types.CreateSinkRequest`): + request (Union[google.cloud.logging_v2.types.CreateSinkRequest, dict]): The request object. The parameters to `CreateSink`. parent (:class:`str`): Required. The resource in which to create the sink: @@ -1063,12 +1065,12 @@ async def create_sink( async def update_sink( self, - request: logging_config.UpdateSinkRequest = None, + request: Union[logging_config.UpdateSinkRequest, dict] = None, *, sink_name: str = None, sink: logging_config.LogSink = None, update_mask: field_mask_pb2.FieldMask = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogSink: @@ -1080,7 +1082,7 @@ async def update_sink( the ``unique_writer_identity`` field. Args: - request (:class:`google.cloud.logging_v2.types.UpdateSinkRequest`): + request (Union[google.cloud.logging_v2.types.UpdateSinkRequest, dict]): The request object. The parameters to `UpdateSink`. sink_name (:class:`str`): Required. The full resource name of the sink to update, @@ -1200,10 +1202,10 @@ async def update_sink( async def delete_sink( self, - request: logging_config.DeleteSinkRequest = None, + request: Union[logging_config.DeleteSinkRequest, dict] = None, *, sink_name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: @@ -1211,7 +1213,7 @@ async def delete_sink( then that service account is also deleted. Args: - request (:class:`google.cloud.logging_v2.types.DeleteSinkRequest`): + request (Union[google.cloud.logging_v2.types.DeleteSinkRequest, dict]): The request object. The parameters to `DeleteSink`. sink_name (:class:`str`): Required. The full resource name of the sink to delete, @@ -1286,17 +1288,17 @@ async def delete_sink( async def list_exclusions( self, - request: logging_config.ListExclusionsRequest = None, + request: Union[logging_config.ListExclusionsRequest, dict] = None, *, parent: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListExclusionsAsyncPager: r"""Lists all the exclusions in a parent resource. Args: - request (:class:`google.cloud.logging_v2.types.ListExclusionsRequest`): + request (Union[google.cloud.logging_v2.types.ListExclusionsRequest, dict]): The request object. The parameters to `ListExclusions`. parent (:class:`str`): Required. The parent resource whose exclusions are to be @@ -1382,17 +1384,17 @@ async def list_exclusions( async def get_exclusion( self, - request: logging_config.GetExclusionRequest = None, + request: Union[logging_config.GetExclusionRequest, dict] = None, *, name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogExclusion: r"""Gets the description of an exclusion. Args: - request (:class:`google.cloud.logging_v2.types.GetExclusionRequest`): + request (Union[google.cloud.logging_v2.types.GetExclusionRequest, dict]): The request object. The parameters to `GetExclusion`. name (:class:`str`): Required. The resource name of an existing exclusion: @@ -1481,11 +1483,11 @@ async def get_exclusion( async def create_exclusion( self, - request: logging_config.CreateExclusionRequest = None, + request: Union[logging_config.CreateExclusionRequest, dict] = None, *, parent: str = None, exclusion: logging_config.LogExclusion = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogExclusion: @@ -1495,7 +1497,7 @@ async def create_exclusion( resource. Args: - request (:class:`google.cloud.logging_v2.types.CreateExclusionRequest`): + request (Union[google.cloud.logging_v2.types.CreateExclusionRequest, dict]): The request object. The parameters to `CreateExclusion`. parent (:class:`str`): Required. The parent resource in which to create the @@ -1584,12 +1586,12 @@ async def create_exclusion( async def update_exclusion( self, - request: logging_config.UpdateExclusionRequest = None, + request: Union[logging_config.UpdateExclusionRequest, dict] = None, *, name: str = None, exclusion: logging_config.LogExclusion = None, update_mask: field_mask_pb2.FieldMask = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogExclusion: @@ -1597,7 +1599,7 @@ async def update_exclusion( exclusion. Args: - request (:class:`google.cloud.logging_v2.types.UpdateExclusionRequest`): + request (Union[google.cloud.logging_v2.types.UpdateExclusionRequest, dict]): The request object. The parameters to `UpdateExclusion`. name (:class:`str`): Required. The resource name of the exclusion to update: @@ -1701,17 +1703,17 @@ async def update_exclusion( async def delete_exclusion( self, - request: logging_config.DeleteExclusionRequest = None, + request: Union[logging_config.DeleteExclusionRequest, dict] = None, *, name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: r"""Deletes an exclusion. Args: - request (:class:`google.cloud.logging_v2.types.DeleteExclusionRequest`): + request (Union[google.cloud.logging_v2.types.DeleteExclusionRequest, dict]): The request object. The parameters to `DeleteExclusion`. name (:class:`str`): Required. The resource name of an existing exclusion to @@ -1785,9 +1787,9 @@ async def delete_exclusion( async def get_cmek_settings( self, - request: logging_config.GetCmekSettingsRequest = None, + request: Union[logging_config.GetCmekSettingsRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.CmekSettings: @@ -1802,7 +1804,7 @@ async def get_cmek_settings( for more information. Args: - request (:class:`google.cloud.logging_v2.types.GetCmekSettingsRequest`): + request (Union[google.cloud.logging_v2.types.GetCmekSettingsRequest, dict]): The request object. The parameters to [GetCmekSettings][google.logging.v2.ConfigServiceV2.GetCmekSettings]. See [Enabling CMEK for Logs @@ -1855,9 +1857,9 @@ async def get_cmek_settings( async def update_cmek_settings( self, - request: logging_config.UpdateCmekSettingsRequest = None, + request: Union[logging_config.UpdateCmekSettingsRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.CmekSettings: @@ -1878,7 +1880,7 @@ async def update_cmek_settings( for more information. Args: - request (:class:`google.cloud.logging_v2.types.UpdateCmekSettingsRequest`): + request (Union[google.cloud.logging_v2.types.UpdateCmekSettingsRequest, dict]): The request object. The parameters to [UpdateCmekSettings][google.logging.v2.ConfigServiceV2.UpdateCmekSettings]. See [Enabling CMEK for Logs @@ -1929,6 +1931,12 @@ async def update_cmek_settings( # Done; return the response. return response + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/logging_v2/services/config_service_v2/client.py b/google/cloud/logging_v2/services/config_service_v2/client.py index 2ef4f49b6..e2c8fe0a5 100644 --- a/google/cloud/logging_v2/services/config_service_v2/client.py +++ b/google/cloud/logging_v2/services/config_service_v2/client.py @@ -17,7 +17,7 @@ from distutils import util import os import re -from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union +from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources from google.api_core import client_options as client_options_lib # type: ignore @@ -30,6 +30,8 @@ from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore +OptionalRetry = Union[retries.Retry, object] + from google.cloud.logging_v2.services.config_service_v2 import pagers from google.cloud.logging_v2.types import logging_config from google.protobuf import field_mask_pb2 # type: ignore @@ -397,25 +399,22 @@ def __init__( client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, - always_use_jwt_access=( - Transport == type(self).get_transport_class("grpc") - or Transport == type(self).get_transport_class("grpc_asyncio") - ), + always_use_jwt_access=True, ) def list_buckets( self, - request: logging_config.ListBucketsRequest = None, + request: Union[logging_config.ListBucketsRequest, dict] = None, *, parent: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListBucketsPager: r"""Lists buckets. Args: - request (google.cloud.logging_v2.types.ListBucketsRequest): + request (Union[google.cloud.logging_v2.types.ListBucketsRequest, dict]): The request object. The parameters to `ListBuckets`. parent (str): Required. The parent resource whose buckets are to be @@ -494,16 +493,16 @@ def list_buckets( def get_bucket( self, - request: logging_config.GetBucketRequest = None, + request: Union[logging_config.GetBucketRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogBucket: r"""Gets a bucket. Args: - request (google.cloud.logging_v2.types.GetBucketRequest): + request (Union[google.cloud.logging_v2.types.GetBucketRequest, dict]): The request object. The parameters to `GetBucket`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -541,9 +540,9 @@ def get_bucket( def create_bucket( self, - request: logging_config.CreateBucketRequest = None, + request: Union[logging_config.CreateBucketRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogBucket: @@ -552,7 +551,7 @@ def create_bucket( cannot be changed. Args: - request (google.cloud.logging_v2.types.CreateBucketRequest): + request (Union[google.cloud.logging_v2.types.CreateBucketRequest, dict]): The request object. The parameters to `CreateBucket`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -590,9 +589,9 @@ def create_bucket( def update_bucket( self, - request: logging_config.UpdateBucketRequest = None, + request: Union[logging_config.UpdateBucketRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogBucket: @@ -609,7 +608,7 @@ def update_bucket( A buckets region may not be modified after it is created. Args: - request (google.cloud.logging_v2.types.UpdateBucketRequest): + request (Union[google.cloud.logging_v2.types.UpdateBucketRequest, dict]): The request object. The parameters to `UpdateBucket`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -647,9 +646,9 @@ def update_bucket( def delete_bucket( self, - request: logging_config.DeleteBucketRequest = None, + request: Union[logging_config.DeleteBucketRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: @@ -658,7 +657,7 @@ def delete_bucket( the bucket will be permanently deleted. Args: - request (google.cloud.logging_v2.types.DeleteBucketRequest): + request (Union[google.cloud.logging_v2.types.DeleteBucketRequest, dict]): The request object. The parameters to `DeleteBucket`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -691,9 +690,9 @@ def delete_bucket( def undelete_bucket( self, - request: logging_config.UndeleteBucketRequest = None, + request: Union[logging_config.UndeleteBucketRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: @@ -701,7 +700,7 @@ def undelete_bucket( may be undeleted within the grace period of 7 days. Args: - request (google.cloud.logging_v2.types.UndeleteBucketRequest): + request (Union[google.cloud.logging_v2.types.UndeleteBucketRequest, dict]): The request object. The parameters to `UndeleteBucket`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -734,17 +733,17 @@ def undelete_bucket( def list_views( self, - request: logging_config.ListViewsRequest = None, + request: Union[logging_config.ListViewsRequest, dict] = None, *, parent: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListViewsPager: r"""Lists views on a bucket. Args: - request (google.cloud.logging_v2.types.ListViewsRequest): + request (Union[google.cloud.logging_v2.types.ListViewsRequest, dict]): The request object. The parameters to `ListViews`. parent (str): Required. The bucket whose views are to be listed: @@ -815,16 +814,16 @@ def list_views( def get_view( self, - request: logging_config.GetViewRequest = None, + request: Union[logging_config.GetViewRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogView: r"""Gets a view. Args: - request (google.cloud.logging_v2.types.GetViewRequest): + request (Union[google.cloud.logging_v2.types.GetViewRequest, dict]): The request object. The parameters to `GetView`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -864,9 +863,9 @@ def get_view( def create_view( self, - request: logging_config.CreateViewRequest = None, + request: Union[logging_config.CreateViewRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogView: @@ -874,7 +873,7 @@ def create_view( contain a maximum of 50 views. Args: - request (google.cloud.logging_v2.types.CreateViewRequest): + request (Union[google.cloud.logging_v2.types.CreateViewRequest, dict]): The request object. The parameters to `CreateView`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -914,9 +913,9 @@ def create_view( def update_view( self, - request: logging_config.UpdateViewRequest = None, + request: Union[logging_config.UpdateViewRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogView: @@ -924,7 +923,7 @@ def update_view( existing view with values from the new view: ``filter``. Args: - request (google.cloud.logging_v2.types.UpdateViewRequest): + request (Union[google.cloud.logging_v2.types.UpdateViewRequest, dict]): The request object. The parameters to `UpdateView`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -964,16 +963,16 @@ def update_view( def delete_view( self, - request: logging_config.DeleteViewRequest = None, + request: Union[logging_config.DeleteViewRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: r"""Deletes a view from a bucket. Args: - request (google.cloud.logging_v2.types.DeleteViewRequest): + request (Union[google.cloud.logging_v2.types.DeleteViewRequest, dict]): The request object. The parameters to `DeleteView`. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. @@ -1006,17 +1005,17 @@ def delete_view( def list_sinks( self, - request: logging_config.ListSinksRequest = None, + request: Union[logging_config.ListSinksRequest, dict] = None, *, parent: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListSinksPager: r"""Lists sinks. Args: - request (google.cloud.logging_v2.types.ListSinksRequest): + request (Union[google.cloud.logging_v2.types.ListSinksRequest, dict]): The request object. The parameters to `ListSinks`. parent (str): Required. The parent resource whose sinks are to be @@ -1091,17 +1090,17 @@ def list_sinks( def get_sink( self, - request: logging_config.GetSinkRequest = None, + request: Union[logging_config.GetSinkRequest, dict] = None, *, sink_name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogSink: r"""Gets a sink. Args: - request (google.cloud.logging_v2.types.GetSinkRequest): + request (Union[google.cloud.logging_v2.types.GetSinkRequest, dict]): The request object. The parameters to `GetSink`. sink_name (str): Required. The resource name of the sink: @@ -1178,11 +1177,11 @@ def get_sink( def create_sink( self, - request: logging_config.CreateSinkRequest = None, + request: Union[logging_config.CreateSinkRequest, dict] = None, *, parent: str = None, sink: logging_config.LogSink = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogSink: @@ -1193,7 +1192,7 @@ def create_sink( entries only from the resource owning the sink. Args: - request (google.cloud.logging_v2.types.CreateSinkRequest): + request (Union[google.cloud.logging_v2.types.CreateSinkRequest, dict]): The request object. The parameters to `CreateSink`. parent (str): Required. The resource in which to create the sink: @@ -1278,12 +1277,12 @@ def create_sink( def update_sink( self, - request: logging_config.UpdateSinkRequest = None, + request: Union[logging_config.UpdateSinkRequest, dict] = None, *, sink_name: str = None, sink: logging_config.LogSink = None, update_mask: field_mask_pb2.FieldMask = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogSink: @@ -1295,7 +1294,7 @@ def update_sink( the ``unique_writer_identity`` field. Args: - request (google.cloud.logging_v2.types.UpdateSinkRequest): + request (Union[google.cloud.logging_v2.types.UpdateSinkRequest, dict]): The request object. The parameters to `UpdateSink`. sink_name (str): Required. The full resource name of the sink to update, @@ -1404,10 +1403,10 @@ def update_sink( def delete_sink( self, - request: logging_config.DeleteSinkRequest = None, + request: Union[logging_config.DeleteSinkRequest, dict] = None, *, sink_name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: @@ -1415,7 +1414,7 @@ def delete_sink( then that service account is also deleted. Args: - request (google.cloud.logging_v2.types.DeleteSinkRequest): + request (Union[google.cloud.logging_v2.types.DeleteSinkRequest, dict]): The request object. The parameters to `DeleteSink`. sink_name (str): Required. The full resource name of the sink to delete, @@ -1479,17 +1478,17 @@ def delete_sink( def list_exclusions( self, - request: logging_config.ListExclusionsRequest = None, + request: Union[logging_config.ListExclusionsRequest, dict] = None, *, parent: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListExclusionsPager: r"""Lists all the exclusions in a parent resource. Args: - request (google.cloud.logging_v2.types.ListExclusionsRequest): + request (Union[google.cloud.logging_v2.types.ListExclusionsRequest, dict]): The request object. The parameters to `ListExclusions`. parent (str): Required. The parent resource whose exclusions are to be @@ -1564,17 +1563,17 @@ def list_exclusions( def get_exclusion( self, - request: logging_config.GetExclusionRequest = None, + request: Union[logging_config.GetExclusionRequest, dict] = None, *, name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogExclusion: r"""Gets the description of an exclusion. Args: - request (google.cloud.logging_v2.types.GetExclusionRequest): + request (Union[google.cloud.logging_v2.types.GetExclusionRequest, dict]): The request object. The parameters to `GetExclusion`. name (str): Required. The resource name of an existing exclusion: @@ -1652,11 +1651,11 @@ def get_exclusion( def create_exclusion( self, - request: logging_config.CreateExclusionRequest = None, + request: Union[logging_config.CreateExclusionRequest, dict] = None, *, parent: str = None, exclusion: logging_config.LogExclusion = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogExclusion: @@ -1666,7 +1665,7 @@ def create_exclusion( resource. Args: - request (google.cloud.logging_v2.types.CreateExclusionRequest): + request (Union[google.cloud.logging_v2.types.CreateExclusionRequest, dict]): The request object. The parameters to `CreateExclusion`. parent (str): Required. The parent resource in which to create the @@ -1755,12 +1754,12 @@ def create_exclusion( def update_exclusion( self, - request: logging_config.UpdateExclusionRequest = None, + request: Union[logging_config.UpdateExclusionRequest, dict] = None, *, name: str = None, exclusion: logging_config.LogExclusion = None, update_mask: field_mask_pb2.FieldMask = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.LogExclusion: @@ -1768,7 +1767,7 @@ def update_exclusion( exclusion. Args: - request (google.cloud.logging_v2.types.UpdateExclusionRequest): + request (Union[google.cloud.logging_v2.types.UpdateExclusionRequest, dict]): The request object. The parameters to `UpdateExclusion`. name (str): Required. The resource name of the exclusion to update: @@ -1872,17 +1871,17 @@ def update_exclusion( def delete_exclusion( self, - request: logging_config.DeleteExclusionRequest = None, + request: Union[logging_config.DeleteExclusionRequest, dict] = None, *, name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: r"""Deletes an exclusion. Args: - request (google.cloud.logging_v2.types.DeleteExclusionRequest): + request (Union[google.cloud.logging_v2.types.DeleteExclusionRequest, dict]): The request object. The parameters to `DeleteExclusion`. name (str): Required. The resource name of an existing exclusion to @@ -1945,9 +1944,9 @@ def delete_exclusion( def get_cmek_settings( self, - request: logging_config.GetCmekSettingsRequest = None, + request: Union[logging_config.GetCmekSettingsRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.CmekSettings: @@ -1962,7 +1961,7 @@ def get_cmek_settings( for more information. Args: - request (google.cloud.logging_v2.types.GetCmekSettingsRequest): + request (Union[google.cloud.logging_v2.types.GetCmekSettingsRequest, dict]): The request object. The parameters to [GetCmekSettings][google.logging.v2.ConfigServiceV2.GetCmekSettings]. See [Enabling CMEK for Logs @@ -2016,9 +2015,9 @@ def get_cmek_settings( def update_cmek_settings( self, - request: logging_config.UpdateCmekSettingsRequest = None, + request: Union[logging_config.UpdateCmekSettingsRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_config.CmekSettings: @@ -2039,7 +2038,7 @@ def update_cmek_settings( for more information. Args: - request (google.cloud.logging_v2.types.UpdateCmekSettingsRequest): + request (Union[google.cloud.logging_v2.types.UpdateCmekSettingsRequest, dict]): The request object. The parameters to [UpdateCmekSettings][google.logging.v2.ConfigServiceV2.UpdateCmekSettings]. See [Enabling CMEK for Logs @@ -2091,6 +2090,19 @@ def update_cmek_settings( # Done; return the response. return response + def __enter__(self): + 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() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/logging_v2/services/config_service_v2/pagers.py b/google/cloud/logging_v2/services/config_service_v2/pagers.py index 6d8e11fb8..b0be053e4 100644 --- a/google/cloud/logging_v2/services/config_service_v2/pagers.py +++ b/google/cloud/logging_v2/services/config_service_v2/pagers.py @@ -15,13 +15,13 @@ # from typing import ( Any, - AsyncIterable, + AsyncIterator, Awaitable, Callable, - Iterable, Sequence, Tuple, Optional, + Iterator, ) from google.cloud.logging_v2.types import logging_config @@ -74,14 +74,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - def pages(self) -> Iterable[logging_config.ListBucketsResponse]: + def pages(self) -> Iterator[logging_config.ListBucketsResponse]: yield self._response while self._response.next_page_token: self._request.page_token = self._response.next_page_token self._response = self._method(self._request, metadata=self._metadata) yield self._response - def __iter__(self) -> Iterable[logging_config.LogBucket]: + def __iter__(self) -> Iterator[logging_config.LogBucket]: for page in self.pages: yield from page.buckets @@ -136,14 +136,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - async def pages(self) -> AsyncIterable[logging_config.ListBucketsResponse]: + async def pages(self) -> AsyncIterator[logging_config.ListBucketsResponse]: 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, metadata=self._metadata) yield self._response - def __aiter__(self) -> AsyncIterable[logging_config.LogBucket]: + def __aiter__(self) -> AsyncIterator[logging_config.LogBucket]: async def async_generator(): async for page in self.pages: for response in page.buckets: @@ -202,14 +202,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - def pages(self) -> Iterable[logging_config.ListViewsResponse]: + def pages(self) -> Iterator[logging_config.ListViewsResponse]: yield self._response while self._response.next_page_token: self._request.page_token = self._response.next_page_token self._response = self._method(self._request, metadata=self._metadata) yield self._response - def __iter__(self) -> Iterable[logging_config.LogView]: + def __iter__(self) -> Iterator[logging_config.LogView]: for page in self.pages: yield from page.views @@ -264,14 +264,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - async def pages(self) -> AsyncIterable[logging_config.ListViewsResponse]: + async def pages(self) -> AsyncIterator[logging_config.ListViewsResponse]: 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, metadata=self._metadata) yield self._response - def __aiter__(self) -> AsyncIterable[logging_config.LogView]: + def __aiter__(self) -> AsyncIterator[logging_config.LogView]: async def async_generator(): async for page in self.pages: for response in page.views: @@ -330,14 +330,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - def pages(self) -> Iterable[logging_config.ListSinksResponse]: + def pages(self) -> Iterator[logging_config.ListSinksResponse]: yield self._response while self._response.next_page_token: self._request.page_token = self._response.next_page_token self._response = self._method(self._request, metadata=self._metadata) yield self._response - def __iter__(self) -> Iterable[logging_config.LogSink]: + def __iter__(self) -> Iterator[logging_config.LogSink]: for page in self.pages: yield from page.sinks @@ -392,14 +392,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - async def pages(self) -> AsyncIterable[logging_config.ListSinksResponse]: + async def pages(self) -> AsyncIterator[logging_config.ListSinksResponse]: 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, metadata=self._metadata) yield self._response - def __aiter__(self) -> AsyncIterable[logging_config.LogSink]: + def __aiter__(self) -> AsyncIterator[logging_config.LogSink]: async def async_generator(): async for page in self.pages: for response in page.sinks: @@ -458,14 +458,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - def pages(self) -> Iterable[logging_config.ListExclusionsResponse]: + def pages(self) -> Iterator[logging_config.ListExclusionsResponse]: yield self._response while self._response.next_page_token: self._request.page_token = self._response.next_page_token self._response = self._method(self._request, metadata=self._metadata) yield self._response - def __iter__(self) -> Iterable[logging_config.LogExclusion]: + def __iter__(self) -> Iterator[logging_config.LogExclusion]: for page in self.pages: yield from page.exclusions @@ -520,14 +520,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - async def pages(self) -> AsyncIterable[logging_config.ListExclusionsResponse]: + async def pages(self) -> AsyncIterator[logging_config.ListExclusionsResponse]: 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, metadata=self._metadata) yield self._response - def __aiter__(self) -> AsyncIterable[logging_config.LogExclusion]: + def __aiter__(self) -> AsyncIterator[logging_config.LogExclusion]: async def async_generator(): async for page in self.pages: for response in page.exclusions: diff --git a/google/cloud/logging_v2/services/config_service_v2/transports/base.py b/google/cloud/logging_v2/services/config_service_v2/transports/base.py index e191687e9..00557f640 100644 --- a/google/cloud/logging_v2/services/config_service_v2/transports/base.py +++ b/google/cloud/logging_v2/services/config_service_v2/transports/base.py @@ -15,7 +15,6 @@ # import abc from typing import Awaitable, Callable, Dict, Optional, Sequence, Union -import packaging.version import pkg_resources import google.auth # type: ignore @@ -36,15 +35,6 @@ except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() -try: - # google.auth.__version__ was added in 1.26.0 - _GOOGLE_AUTH_VERSION = google.auth.__version__ -except AttributeError: - try: # try pkg_resources if it is available - _GOOGLE_AUTH_VERSION = pkg_resources.get_distribution("google-auth").version - except pkg_resources.DistributionNotFound: # pragma: NO COVER - _GOOGLE_AUTH_VERSION = None - class ConfigServiceV2Transport(abc.ABC): """Abstract transport class for ConfigServiceV2.""" @@ -99,7 +89,7 @@ def __init__( host += ":443" self._host = host - scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} # Save the scopes. self._scopes = scopes @@ -121,7 +111,7 @@ def __init__( **scopes_kwargs, quota_project_id=quota_project_id ) - # If the credentials is service account credentials, then always try to use self signed JWT. + # 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) @@ -132,29 +122,6 @@ def __init__( # Save the credentials. self._credentials = credentials - # TODO(busunkim): This method is in the base transport - # to avoid duplicating code across the transport classes. These functions - # should be deleted once the minimum required versions of google-auth is increased. - - # TODO: Remove this function once google-auth >= 1.25.0 is required - @classmethod - def _get_scopes_kwargs( - cls, host: str, scopes: Optional[Sequence[str]] - ) -> Dict[str, Optional[Sequence[str]]]: - """Returns scopes kwargs to pass to google-auth methods depending on the google-auth version""" - - scopes_kwargs = {} - - if _GOOGLE_AUTH_VERSION and ( - packaging.version.parse(_GOOGLE_AUTH_VERSION) - >= packaging.version.parse("1.25.0") - ): - scopes_kwargs = {"scopes": scopes, "default_scopes": cls.AUTH_SCOPES} - else: - scopes_kwargs = {"scopes": scopes or cls.AUTH_SCOPES} - - return scopes_kwargs - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -322,6 +289,15 @@ def _prep_wrapped_messages(self, 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_buckets( self, diff --git a/google/cloud/logging_v2/services/config_service_v2/transports/grpc.py b/google/cloud/logging_v2/services/config_service_v2/transports/grpc.py index ccd766fa7..cd06eac41 100644 --- a/google/cloud/logging_v2/services/config_service_v2/transports/grpc.py +++ b/google/cloud/logging_v2/services/config_service_v2/transports/grpc.py @@ -81,16 +81,16 @@ def __init__( api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or applicatin default SSL credentials. + ``client_cert_source`` 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 grpc channel. It is ignored if ``channel`` is provided. + for the grpc channel. It is ignored if ``channel`` is provided. client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure mutual TLS channel. It is + both in PEM format. It is used to configure a mutual TLS channel. It is ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. @@ -883,5 +883,8 @@ def update_cmek_settings( ) return self._stubs["update_cmek_settings"] + def close(self): + self.grpc_channel.close() + __all__ = ("ConfigServiceV2GrpcTransport",) diff --git a/google/cloud/logging_v2/services/config_service_v2/transports/grpc_asyncio.py b/google/cloud/logging_v2/services/config_service_v2/transports/grpc_asyncio.py index 3b8139e1e..54615a125 100644 --- a/google/cloud/logging_v2/services/config_service_v2/transports/grpc_asyncio.py +++ b/google/cloud/logging_v2/services/config_service_v2/transports/grpc_asyncio.py @@ -20,7 +20,6 @@ from google.api_core import grpc_helpers_async # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore -import packaging.version import grpc # type: ignore from grpc.experimental import aio # type: ignore @@ -128,16 +127,16 @@ def __init__( api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or applicatin default SSL credentials. + ``client_cert_source`` 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 grpc channel. It is ignored if ``channel`` is provided. + for the grpc channel. It is ignored if ``channel`` is provided. client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure mutual TLS channel. It is + both in PEM format. It is used to configure a mutual TLS channel. It is ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. @@ -915,5 +914,8 @@ def update_cmek_settings( ) return self._stubs["update_cmek_settings"] + def close(self): + return self.grpc_channel.close() + __all__ = ("ConfigServiceV2GrpcAsyncIOTransport",) diff --git a/google/cloud/logging_v2/services/logging_service_v2/async_client.py b/google/cloud/logging_v2/services/logging_service_v2/async_client.py index 6a11e96cb..0b927dea9 100644 --- a/google/cloud/logging_v2/services/logging_service_v2/async_client.py +++ b/google/cloud/logging_v2/services/logging_service_v2/async_client.py @@ -28,13 +28,15 @@ ) import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore +from google.api_core.client_options import ClientOptions # type: ignore from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore +OptionalRetry = Union[retries.Retry, object] + from google.api import monitored_resource_pb2 # type: ignore from google.cloud.logging_v2.services.logging_service_v2 import pagers from google.cloud.logging_v2.types import log_entry @@ -174,10 +176,10 @@ def __init__( async def delete_log( self, - request: logging.DeleteLogRequest = None, + request: Union[logging.DeleteLogRequest, dict] = None, *, log_name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: @@ -188,7 +190,7 @@ async def delete_log( with a timestamp before the operation will be deleted. Args: - request (:class:`google.cloud.logging_v2.types.DeleteLogRequest`): + request (Union[google.cloud.logging_v2.types.DeleteLogRequest, dict]): The request object. The parameters to DeleteLog. log_name (:class:`str`): Required. The resource name of the log to delete: @@ -264,13 +266,13 @@ async def delete_log( async def write_log_entries( self, - request: logging.WriteLogEntriesRequest = None, + request: Union[logging.WriteLogEntriesRequest, dict] = None, *, log_name: str = None, resource: monitored_resource_pb2.MonitoredResource = None, labels: Sequence[logging.WriteLogEntriesRequest.LabelsEntry] = None, entries: Sequence[log_entry.LogEntry] = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging.WriteLogEntriesResponse: @@ -283,7 +285,7 @@ async def write_log_entries( organizations, billing accounts or folders) Args: - request (:class:`google.cloud.logging_v2.types.WriteLogEntriesRequest`): + request (Union[google.cloud.logging_v2.types.WriteLogEntriesRequest, dict]): The request object. The parameters to WriteLogEntries. log_name (:class:`str`): Optional. A default log resource name that is assigned @@ -434,12 +436,12 @@ async def write_log_entries( async def list_log_entries( self, - request: logging.ListLogEntriesRequest = None, + request: Union[logging.ListLogEntriesRequest, dict] = None, *, resource_names: Sequence[str] = None, filter: str = None, order_by: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListLogEntriesAsyncPager: @@ -449,7 +451,7 @@ async def list_log_entries( Logs `__. Args: - request (:class:`google.cloud.logging_v2.types.ListLogEntriesRequest`): + request (Union[google.cloud.logging_v2.types.ListLogEntriesRequest, dict]): The request object. The parameters to `ListLogEntries`. resource_names (:class:`Sequence[str]`): Required. Names of one or more parent resources from @@ -569,9 +571,9 @@ async def list_log_entries( async def list_monitored_resource_descriptors( self, - request: logging.ListMonitoredResourceDescriptorsRequest = None, + request: Union[logging.ListMonitoredResourceDescriptorsRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListMonitoredResourceDescriptorsAsyncPager: @@ -579,7 +581,7 @@ async def list_monitored_resource_descriptors( used by Logging. Args: - request (:class:`google.cloud.logging_v2.types.ListMonitoredResourceDescriptorsRequest`): + request (Union[google.cloud.logging_v2.types.ListMonitoredResourceDescriptorsRequest, dict]): The request object. The parameters to ListMonitoredResourceDescriptors retry (google.api_core.retry.Retry): Designation of what errors, if any, @@ -633,10 +635,10 @@ async def list_monitored_resource_descriptors( async def list_logs( self, - request: logging.ListLogsRequest = None, + request: Union[logging.ListLogsRequest, dict] = None, *, parent: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListLogsAsyncPager: @@ -645,7 +647,7 @@ async def list_logs( listed. Args: - request (:class:`google.cloud.logging_v2.types.ListLogsRequest`): + request (Union[google.cloud.logging_v2.types.ListLogsRequest, dict]): The request object. The parameters to ListLogs. parent (:class:`str`): Required. The resource name that owns the logs: @@ -732,7 +734,7 @@ def tail_log_entries( self, requests: AsyncIterator[logging.TailLogEntriesRequest] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> Awaitable[AsyncIterable[logging.TailLogEntriesResponse]]: @@ -779,6 +781,12 @@ def tail_log_entries( # Done; return the response. return response + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/logging_v2/services/logging_service_v2/client.py b/google/cloud/logging_v2/services/logging_service_v2/client.py index c5dba2d04..8e64d9024 100644 --- a/google/cloud/logging_v2/services/logging_service_v2/client.py +++ b/google/cloud/logging_v2/services/logging_service_v2/client.py @@ -17,17 +17,7 @@ from distutils import util import os import re -from typing import ( - Callable, - Dict, - Optional, - Iterable, - Iterator, - Sequence, - Tuple, - Type, - Union, -) +from typing import Dict, Optional, Iterable, Iterator, Sequence, Tuple, Type, Union import pkg_resources from google.api_core import client_options as client_options_lib # type: ignore @@ -40,6 +30,8 @@ from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore +OptionalRetry = Union[retries.Retry, object] + from google.api import monitored_resource_pb2 # type: ignore from google.cloud.logging_v2.services.logging_service_v2 import pagers from google.cloud.logging_v2.types import log_entry @@ -351,18 +343,15 @@ def __init__( client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, - always_use_jwt_access=( - Transport == type(self).get_transport_class("grpc") - or Transport == type(self).get_transport_class("grpc_asyncio") - ), + always_use_jwt_access=True, ) def delete_log( self, - request: logging.DeleteLogRequest = None, + request: Union[logging.DeleteLogRequest, dict] = None, *, log_name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: @@ -373,7 +362,7 @@ def delete_log( with a timestamp before the operation will be deleted. Args: - request (google.cloud.logging_v2.types.DeleteLogRequest): + request (Union[google.cloud.logging_v2.types.DeleteLogRequest, dict]): The request object. The parameters to DeleteLog. log_name (str): Required. The resource name of the log to delete: @@ -438,13 +427,13 @@ def delete_log( def write_log_entries( self, - request: logging.WriteLogEntriesRequest = None, + request: Union[logging.WriteLogEntriesRequest, dict] = None, *, log_name: str = None, resource: monitored_resource_pb2.MonitoredResource = None, labels: Sequence[logging.WriteLogEntriesRequest.LabelsEntry] = None, entries: Sequence[log_entry.LogEntry] = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging.WriteLogEntriesResponse: @@ -457,7 +446,7 @@ def write_log_entries( organizations, billing accounts or folders) Args: - request (google.cloud.logging_v2.types.WriteLogEntriesRequest): + request (Union[google.cloud.logging_v2.types.WriteLogEntriesRequest, dict]): The request object. The parameters to WriteLogEntries. log_name (str): Optional. A default log resource name that is assigned @@ -596,12 +585,12 @@ def write_log_entries( def list_log_entries( self, - request: logging.ListLogEntriesRequest = None, + request: Union[logging.ListLogEntriesRequest, dict] = None, *, resource_names: Sequence[str] = None, filter: str = None, order_by: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListLogEntriesPager: @@ -611,7 +600,7 @@ def list_log_entries( Logs `__. Args: - request (google.cloud.logging_v2.types.ListLogEntriesRequest): + request (Union[google.cloud.logging_v2.types.ListLogEntriesRequest, dict]): The request object. The parameters to `ListLogEntries`. resource_names (Sequence[str]): Required. Names of one or more parent resources from @@ -720,9 +709,9 @@ def list_log_entries( def list_monitored_resource_descriptors( self, - request: logging.ListMonitoredResourceDescriptorsRequest = None, + request: Union[logging.ListMonitoredResourceDescriptorsRequest, dict] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListMonitoredResourceDescriptorsPager: @@ -730,7 +719,7 @@ def list_monitored_resource_descriptors( used by Logging. Args: - request (google.cloud.logging_v2.types.ListMonitoredResourceDescriptorsRequest): + request (Union[google.cloud.logging_v2.types.ListMonitoredResourceDescriptorsRequest, dict]): The request object. The parameters to ListMonitoredResourceDescriptors retry (google.api_core.retry.Retry): Designation of what errors, if any, @@ -776,10 +765,10 @@ def list_monitored_resource_descriptors( def list_logs( self, - request: logging.ListLogsRequest = None, + request: Union[logging.ListLogsRequest, dict] = None, *, parent: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListLogsPager: @@ -788,7 +777,7 @@ def list_logs( listed. Args: - request (google.cloud.logging_v2.types.ListLogsRequest): + request (Union[google.cloud.logging_v2.types.ListLogsRequest, dict]): The request object. The parameters to ListLogs. parent (str): Required. The resource name that owns the logs: @@ -864,7 +853,7 @@ def tail_log_entries( self, requests: Iterator[logging.TailLogEntriesRequest] = None, *, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> Iterable[logging.TailLogEntriesResponse]: @@ -896,6 +885,19 @@ def tail_log_entries( # Done; return the response. return response + def __enter__(self): + 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() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/logging_v2/services/logging_service_v2/pagers.py b/google/cloud/logging_v2/services/logging_service_v2/pagers.py index b06007cb4..ca4d01fac 100644 --- a/google/cloud/logging_v2/services/logging_service_v2/pagers.py +++ b/google/cloud/logging_v2/services/logging_service_v2/pagers.py @@ -15,13 +15,13 @@ # from typing import ( Any, - AsyncIterable, + AsyncIterator, Awaitable, Callable, - Iterable, Sequence, Tuple, Optional, + Iterator, ) from google.api import monitored_resource_pb2 # type: ignore @@ -76,14 +76,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - def pages(self) -> Iterable[logging.ListLogEntriesResponse]: + def pages(self) -> Iterator[logging.ListLogEntriesResponse]: yield self._response while self._response.next_page_token: self._request.page_token = self._response.next_page_token self._response = self._method(self._request, metadata=self._metadata) yield self._response - def __iter__(self) -> Iterable[log_entry.LogEntry]: + def __iter__(self) -> Iterator[log_entry.LogEntry]: for page in self.pages: yield from page.entries @@ -138,14 +138,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - async def pages(self) -> AsyncIterable[logging.ListLogEntriesResponse]: + async def pages(self) -> AsyncIterator[logging.ListLogEntriesResponse]: 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, metadata=self._metadata) yield self._response - def __aiter__(self) -> AsyncIterable[log_entry.LogEntry]: + def __aiter__(self) -> AsyncIterator[log_entry.LogEntry]: async def async_generator(): async for page in self.pages: for response in page.entries: @@ -204,14 +204,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - def pages(self) -> Iterable[logging.ListMonitoredResourceDescriptorsResponse]: + def pages(self) -> Iterator[logging.ListMonitoredResourceDescriptorsResponse]: yield self._response while self._response.next_page_token: self._request.page_token = self._response.next_page_token self._response = self._method(self._request, metadata=self._metadata) yield self._response - def __iter__(self) -> Iterable[monitored_resource_pb2.MonitoredResourceDescriptor]: + def __iter__(self) -> Iterator[monitored_resource_pb2.MonitoredResourceDescriptor]: for page in self.pages: yield from page.resource_descriptors @@ -270,7 +270,7 @@ def __getattr__(self, name: str) -> Any: @property async def pages( self, - ) -> AsyncIterable[logging.ListMonitoredResourceDescriptorsResponse]: + ) -> AsyncIterator[logging.ListMonitoredResourceDescriptorsResponse]: yield self._response while self._response.next_page_token: self._request.page_token = self._response.next_page_token @@ -279,7 +279,7 @@ async def pages( def __aiter__( self, - ) -> AsyncIterable[monitored_resource_pb2.MonitoredResourceDescriptor]: + ) -> AsyncIterator[monitored_resource_pb2.MonitoredResourceDescriptor]: async def async_generator(): async for page in self.pages: for response in page.resource_descriptors: @@ -338,14 +338,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - def pages(self) -> Iterable[logging.ListLogsResponse]: + def pages(self) -> Iterator[logging.ListLogsResponse]: yield self._response while self._response.next_page_token: self._request.page_token = self._response.next_page_token self._response = self._method(self._request, metadata=self._metadata) yield self._response - def __iter__(self) -> Iterable[str]: + def __iter__(self) -> Iterator[str]: for page in self.pages: yield from page.log_names @@ -400,14 +400,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - async def pages(self) -> AsyncIterable[logging.ListLogsResponse]: + async def pages(self) -> AsyncIterator[logging.ListLogsResponse]: 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, metadata=self._metadata) yield self._response - def __aiter__(self) -> AsyncIterable[str]: + def __aiter__(self) -> AsyncIterator[str]: async def async_generator(): async for page in self.pages: for response in page.log_names: diff --git a/google/cloud/logging_v2/services/logging_service_v2/transports/base.py b/google/cloud/logging_v2/services/logging_service_v2/transports/base.py index fb5e3c8b0..556488467 100644 --- a/google/cloud/logging_v2/services/logging_service_v2/transports/base.py +++ b/google/cloud/logging_v2/services/logging_service_v2/transports/base.py @@ -15,7 +15,6 @@ # import abc from typing import Awaitable, Callable, Dict, Optional, Sequence, Union -import packaging.version import pkg_resources import google.auth # type: ignore @@ -36,15 +35,6 @@ except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() -try: - # google.auth.__version__ was added in 1.26.0 - _GOOGLE_AUTH_VERSION = google.auth.__version__ -except AttributeError: - try: # try pkg_resources if it is available - _GOOGLE_AUTH_VERSION = pkg_resources.get_distribution("google-auth").version - except pkg_resources.DistributionNotFound: # pragma: NO COVER - _GOOGLE_AUTH_VERSION = None - class LoggingServiceV2Transport(abc.ABC): """Abstract transport class for LoggingServiceV2.""" @@ -100,7 +90,7 @@ def __init__( host += ":443" self._host = host - scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} # Save the scopes. self._scopes = scopes @@ -122,7 +112,7 @@ def __init__( **scopes_kwargs, quota_project_id=quota_project_id ) - # If the credentials is service account credentials, then always try to use self signed JWT. + # 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) @@ -133,29 +123,6 @@ def __init__( # Save the credentials. self._credentials = credentials - # TODO(busunkim): This method is in the base transport - # to avoid duplicating code across the transport classes. These functions - # should be deleted once the minimum required versions of google-auth is increased. - - # TODO: Remove this function once google-auth >= 1.25.0 is required - @classmethod - def _get_scopes_kwargs( - cls, host: str, scopes: Optional[Sequence[str]] - ) -> Dict[str, Optional[Sequence[str]]]: - """Returns scopes kwargs to pass to google-auth methods depending on the google-auth version""" - - scopes_kwargs = {} - - if _GOOGLE_AUTH_VERSION and ( - packaging.version.parse(_GOOGLE_AUTH_VERSION) - >= packaging.version.parse("1.25.0") - ): - scopes_kwargs = {"scopes": scopes, "default_scopes": cls.AUTH_SCOPES} - else: - scopes_kwargs = {"scopes": scopes or cls.AUTH_SCOPES} - - return scopes_kwargs - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -257,6 +224,15 @@ def _prep_wrapped_messages(self, 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 delete_log( self, diff --git a/google/cloud/logging_v2/services/logging_service_v2/transports/grpc.py b/google/cloud/logging_v2/services/logging_service_v2/transports/grpc.py index fddf03988..146f97cbb 100644 --- a/google/cloud/logging_v2/services/logging_service_v2/transports/grpc.py +++ b/google/cloud/logging_v2/services/logging_service_v2/transports/grpc.py @@ -81,16 +81,16 @@ def __init__( api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or applicatin default SSL credentials. + ``client_cert_source`` 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 grpc channel. It is ignored if ``channel`` is provided. + for the grpc channel. It is ignored if ``channel`` is provided. client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure mutual TLS channel. It is + both in PEM format. It is used to configure a mutual TLS channel. It is ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. @@ -404,5 +404,8 @@ def tail_log_entries( ) return self._stubs["tail_log_entries"] + def close(self): + self.grpc_channel.close() + __all__ = ("LoggingServiceV2GrpcTransport",) diff --git a/google/cloud/logging_v2/services/logging_service_v2/transports/grpc_asyncio.py b/google/cloud/logging_v2/services/logging_service_v2/transports/grpc_asyncio.py index 3e158cd6f..84e765cf4 100644 --- a/google/cloud/logging_v2/services/logging_service_v2/transports/grpc_asyncio.py +++ b/google/cloud/logging_v2/services/logging_service_v2/transports/grpc_asyncio.py @@ -20,7 +20,6 @@ from google.api_core import grpc_helpers_async # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore -import packaging.version import grpc # type: ignore from grpc.experimental import aio # type: ignore @@ -128,16 +127,16 @@ def __init__( api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or applicatin default SSL credentials. + ``client_cert_source`` 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 grpc channel. It is ignored if ``channel`` is provided. + for the grpc channel. It is ignored if ``channel`` is provided. client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure mutual TLS channel. It is + both in PEM format. It is used to configure a mutual TLS channel. It is ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. @@ -415,5 +414,8 @@ def tail_log_entries( ) return self._stubs["tail_log_entries"] + def close(self): + return self.grpc_channel.close() + __all__ = ("LoggingServiceV2GrpcAsyncIOTransport",) diff --git a/google/cloud/logging_v2/services/metrics_service_v2/async_client.py b/google/cloud/logging_v2/services/metrics_service_v2/async_client.py index defd64a13..1e3213a4c 100644 --- a/google/cloud/logging_v2/services/metrics_service_v2/async_client.py +++ b/google/cloud/logging_v2/services/metrics_service_v2/async_client.py @@ -19,13 +19,15 @@ from typing import Dict, Sequence, Tuple, Type, Union import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore +from google.api_core.client_options import ClientOptions # type: ignore from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore +OptionalRetry = Union[retries.Retry, object] + from google.api import distribution_pb2 # type: ignore from google.api import metric_pb2 # type: ignore from google.cloud.logging_v2.services.metrics_service_v2 import pagers @@ -166,17 +168,17 @@ def __init__( async def list_log_metrics( self, - request: logging_metrics.ListLogMetricsRequest = None, + request: Union[logging_metrics.ListLogMetricsRequest, dict] = None, *, parent: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListLogMetricsAsyncPager: r"""Lists logs-based metrics. Args: - request (:class:`google.cloud.logging_v2.types.ListLogMetricsRequest`): + request (Union[google.cloud.logging_v2.types.ListLogMetricsRequest, dict]): The request object. The parameters to ListLogMetrics. parent (:class:`str`): Required. The name of the project containing the @@ -259,17 +261,17 @@ async def list_log_metrics( async def get_log_metric( self, - request: logging_metrics.GetLogMetricRequest = None, + request: Union[logging_metrics.GetLogMetricRequest, dict] = None, *, metric_name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_metrics.LogMetric: r"""Gets a logs-based metric. Args: - request (:class:`google.cloud.logging_v2.types.GetLogMetricRequest`): + request (Union[google.cloud.logging_v2.types.GetLogMetricRequest, dict]): The request object. The parameters to GetLogMetric. metric_name (:class:`str`): Required. The resource name of the desired metric: @@ -354,18 +356,18 @@ async def get_log_metric( async def create_log_metric( self, - request: logging_metrics.CreateLogMetricRequest = None, + request: Union[logging_metrics.CreateLogMetricRequest, dict] = None, *, parent: str = None, metric: logging_metrics.LogMetric = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_metrics.LogMetric: r"""Creates a logs-based metric. Args: - request (:class:`google.cloud.logging_v2.types.CreateLogMetricRequest`): + request (Union[google.cloud.logging_v2.types.CreateLogMetricRequest, dict]): The request object. The parameters to CreateLogMetric. parent (:class:`str`): Required. The resource name of the project in which to @@ -450,18 +452,18 @@ async def create_log_metric( async def update_log_metric( self, - request: logging_metrics.UpdateLogMetricRequest = None, + request: Union[logging_metrics.UpdateLogMetricRequest, dict] = None, *, metric_name: str = None, metric: logging_metrics.LogMetric = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_metrics.LogMetric: r"""Creates or updates a logs-based metric. Args: - request (:class:`google.cloud.logging_v2.types.UpdateLogMetricRequest`): + request (Union[google.cloud.logging_v2.types.UpdateLogMetricRequest, dict]): The request object. The parameters to UpdateLogMetric. metric_name (:class:`str`): Required. The resource name of the metric to update: @@ -558,17 +560,17 @@ async def update_log_metric( async def delete_log_metric( self, - request: logging_metrics.DeleteLogMetricRequest = None, + request: Union[logging_metrics.DeleteLogMetricRequest, dict] = None, *, metric_name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: r"""Deletes a logs-based metric. Args: - request (:class:`google.cloud.logging_v2.types.DeleteLogMetricRequest`): + request (Union[google.cloud.logging_v2.types.DeleteLogMetricRequest, dict]): The request object. The parameters to DeleteLogMetric. metric_name (:class:`str`): Required. The resource name of the metric to delete: @@ -635,6 +637,12 @@ async def delete_log_metric( request, retry=retry, timeout=timeout, metadata=metadata, ) + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/logging_v2/services/metrics_service_v2/client.py b/google/cloud/logging_v2/services/metrics_service_v2/client.py index 9749b5eff..9290d62cc 100644 --- a/google/cloud/logging_v2/services/metrics_service_v2/client.py +++ b/google/cloud/logging_v2/services/metrics_service_v2/client.py @@ -17,7 +17,7 @@ from distutils import util import os import re -from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union +from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources from google.api_core import client_options as client_options_lib # type: ignore @@ -30,6 +30,8 @@ from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore +OptionalRetry = Union[retries.Retry, object] + from google.api import distribution_pb2 # type: ignore from google.api import metric_pb2 # type: ignore from google.cloud.logging_v2.services.metrics_service_v2 import pagers @@ -344,25 +346,22 @@ def __init__( client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, - always_use_jwt_access=( - Transport == type(self).get_transport_class("grpc") - or Transport == type(self).get_transport_class("grpc_asyncio") - ), + always_use_jwt_access=True, ) def list_log_metrics( self, - request: logging_metrics.ListLogMetricsRequest = None, + request: Union[logging_metrics.ListLogMetricsRequest, dict] = None, *, parent: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> pagers.ListLogMetricsPager: r"""Lists logs-based metrics. Args: - request (google.cloud.logging_v2.types.ListLogMetricsRequest): + request (Union[google.cloud.logging_v2.types.ListLogMetricsRequest, dict]): The request object. The parameters to ListLogMetrics. parent (str): Required. The name of the project containing the @@ -434,17 +433,17 @@ def list_log_metrics( def get_log_metric( self, - request: logging_metrics.GetLogMetricRequest = None, + request: Union[logging_metrics.GetLogMetricRequest, dict] = None, *, metric_name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_metrics.LogMetric: r"""Gets a logs-based metric. Args: - request (google.cloud.logging_v2.types.GetLogMetricRequest): + request (Union[google.cloud.logging_v2.types.GetLogMetricRequest, dict]): The request object. The parameters to GetLogMetric. metric_name (str): Required. The resource name of the desired metric: @@ -518,18 +517,18 @@ def get_log_metric( def create_log_metric( self, - request: logging_metrics.CreateLogMetricRequest = None, + request: Union[logging_metrics.CreateLogMetricRequest, dict] = None, *, parent: str = None, metric: logging_metrics.LogMetric = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_metrics.LogMetric: r"""Creates a logs-based metric. Args: - request (google.cloud.logging_v2.types.CreateLogMetricRequest): + request (Union[google.cloud.logging_v2.types.CreateLogMetricRequest, dict]): The request object. The parameters to CreateLogMetric. parent (str): Required. The resource name of the project in which to @@ -614,18 +613,18 @@ def create_log_metric( def update_log_metric( self, - request: logging_metrics.UpdateLogMetricRequest = None, + request: Union[logging_metrics.UpdateLogMetricRequest, dict] = None, *, metric_name: str = None, metric: logging_metrics.LogMetric = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> logging_metrics.LogMetric: r"""Creates or updates a logs-based metric. Args: - request (google.cloud.logging_v2.types.UpdateLogMetricRequest): + request (Union[google.cloud.logging_v2.types.UpdateLogMetricRequest, dict]): The request object. The parameters to UpdateLogMetric. metric_name (str): Required. The resource name of the metric to update: @@ -711,17 +710,17 @@ def update_log_metric( def delete_log_metric( self, - request: logging_metrics.DeleteLogMetricRequest = None, + request: Union[logging_metrics.DeleteLogMetricRequest, dict] = None, *, metric_name: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> None: r"""Deletes a logs-based metric. Args: - request (google.cloud.logging_v2.types.DeleteLogMetricRequest): + request (Union[google.cloud.logging_v2.types.DeleteLogMetricRequest, dict]): The request object. The parameters to DeleteLogMetric. metric_name (str): Required. The resource name of the metric to delete: @@ -777,6 +776,19 @@ def delete_log_metric( request, retry=retry, timeout=timeout, metadata=metadata, ) + def __enter__(self): + 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() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/google/cloud/logging_v2/services/metrics_service_v2/pagers.py b/google/cloud/logging_v2/services/metrics_service_v2/pagers.py index 8ff178d24..7026e3858 100644 --- a/google/cloud/logging_v2/services/metrics_service_v2/pagers.py +++ b/google/cloud/logging_v2/services/metrics_service_v2/pagers.py @@ -15,13 +15,13 @@ # from typing import ( Any, - AsyncIterable, + AsyncIterator, Awaitable, Callable, - Iterable, Sequence, Tuple, Optional, + Iterator, ) from google.cloud.logging_v2.types import logging_metrics @@ -74,14 +74,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - def pages(self) -> Iterable[logging_metrics.ListLogMetricsResponse]: + def pages(self) -> Iterator[logging_metrics.ListLogMetricsResponse]: yield self._response while self._response.next_page_token: self._request.page_token = self._response.next_page_token self._response = self._method(self._request, metadata=self._metadata) yield self._response - def __iter__(self) -> Iterable[logging_metrics.LogMetric]: + def __iter__(self) -> Iterator[logging_metrics.LogMetric]: for page in self.pages: yield from page.metrics @@ -136,14 +136,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - async def pages(self) -> AsyncIterable[logging_metrics.ListLogMetricsResponse]: + async def pages(self) -> AsyncIterator[logging_metrics.ListLogMetricsResponse]: 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, metadata=self._metadata) yield self._response - def __aiter__(self) -> AsyncIterable[logging_metrics.LogMetric]: + def __aiter__(self) -> AsyncIterator[logging_metrics.LogMetric]: async def async_generator(): async for page in self.pages: for response in page.metrics: diff --git a/google/cloud/logging_v2/services/metrics_service_v2/transports/base.py b/google/cloud/logging_v2/services/metrics_service_v2/transports/base.py index f62eb0046..e3105748a 100644 --- a/google/cloud/logging_v2/services/metrics_service_v2/transports/base.py +++ b/google/cloud/logging_v2/services/metrics_service_v2/transports/base.py @@ -15,7 +15,6 @@ # import abc from typing import Awaitable, Callable, Dict, Optional, Sequence, Union -import packaging.version import pkg_resources import google.auth # type: ignore @@ -36,15 +35,6 @@ except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() -try: - # google.auth.__version__ was added in 1.26.0 - _GOOGLE_AUTH_VERSION = google.auth.__version__ -except AttributeError: - try: # try pkg_resources if it is available - _GOOGLE_AUTH_VERSION = pkg_resources.get_distribution("google-auth").version - except pkg_resources.DistributionNotFound: # pragma: NO COVER - _GOOGLE_AUTH_VERSION = None - class MetricsServiceV2Transport(abc.ABC): """Abstract transport class for MetricsServiceV2.""" @@ -100,7 +90,7 @@ def __init__( host += ":443" self._host = host - scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} # Save the scopes. self._scopes = scopes @@ -122,7 +112,7 @@ def __init__( **scopes_kwargs, quota_project_id=quota_project_id ) - # If the credentials is service account credentials, then always try to use self signed JWT. + # 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) @@ -133,29 +123,6 @@ def __init__( # Save the credentials. self._credentials = credentials - # TODO(busunkim): This method is in the base transport - # to avoid duplicating code across the transport classes. These functions - # should be deleted once the minimum required versions of google-auth is increased. - - # TODO: Remove this function once google-auth >= 1.25.0 is required - @classmethod - def _get_scopes_kwargs( - cls, host: str, scopes: Optional[Sequence[str]] - ) -> Dict[str, Optional[Sequence[str]]]: - """Returns scopes kwargs to pass to google-auth methods depending on the google-auth version""" - - scopes_kwargs = {} - - if _GOOGLE_AUTH_VERSION and ( - packaging.version.parse(_GOOGLE_AUTH_VERSION) - >= packaging.version.parse("1.25.0") - ): - scopes_kwargs = {"scopes": scopes, "default_scopes": cls.AUTH_SCOPES} - else: - scopes_kwargs = {"scopes": scopes or cls.AUTH_SCOPES} - - return scopes_kwargs - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -228,6 +195,15 @@ def _prep_wrapped_messages(self, 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_log_metrics( self, diff --git a/google/cloud/logging_v2/services/metrics_service_v2/transports/grpc.py b/google/cloud/logging_v2/services/metrics_service_v2/transports/grpc.py index 6a7a2c6a6..4dc00d79d 100644 --- a/google/cloud/logging_v2/services/metrics_service_v2/transports/grpc.py +++ b/google/cloud/logging_v2/services/metrics_service_v2/transports/grpc.py @@ -81,16 +81,16 @@ def __init__( api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or applicatin default SSL credentials. + ``client_cert_source`` 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 grpc channel. It is ignored if ``channel`` is provided. + for the grpc channel. It is ignored if ``channel`` is provided. client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure mutual TLS channel. It is + both in PEM format. It is used to configure a mutual TLS channel. It is ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. @@ -358,5 +358,8 @@ def delete_log_metric( ) return self._stubs["delete_log_metric"] + def close(self): + self.grpc_channel.close() + __all__ = ("MetricsServiceV2GrpcTransport",) diff --git a/google/cloud/logging_v2/services/metrics_service_v2/transports/grpc_asyncio.py b/google/cloud/logging_v2/services/metrics_service_v2/transports/grpc_asyncio.py index d2d9b6188..956f53b1d 100644 --- a/google/cloud/logging_v2/services/metrics_service_v2/transports/grpc_asyncio.py +++ b/google/cloud/logging_v2/services/metrics_service_v2/transports/grpc_asyncio.py @@ -20,7 +20,6 @@ from google.api_core import grpc_helpers_async # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore -import packaging.version import grpc # type: ignore from grpc.experimental import aio # type: ignore @@ -128,16 +127,16 @@ def __init__( api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. If provided, it overrides the ``host`` argument and tries to create a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or applicatin default SSL credentials. + ``client_cert_source`` 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 grpc channel. It is ignored if ``channel`` is provided. + for the grpc channel. It is ignored if ``channel`` is provided. client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure mutual TLS channel. It is + both in PEM format. It is used to configure a mutual TLS channel. It is ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. @@ -368,5 +367,8 @@ def delete_log_metric( ) return self._stubs["delete_log_metric"] + def close(self): + return self.grpc_channel.close() + __all__ = ("MetricsServiceV2GrpcAsyncIOTransport",) diff --git a/google/cloud/logging_v2/types/log_entry.py b/google/cloud/logging_v2/types/log_entry.py index 6c57b22d5..99331d327 100644 --- a/google/cloud/logging_v2/types/log_entry.py +++ b/google/cloud/logging_v2/types/log_entry.py @@ -31,6 +31,14 @@ class LogEntry(proto.Message): r"""An individual entry in a log. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: log_name (str): Required. The resource name of the log to which this log @@ -79,12 +87,15 @@ class LogEntry(proto.Message): "type.googleapis.com/google.cloud.audit.AuditLog" "type.googleapis.com/google.appengine.logging.v1.RequestLog". + This field is a member of `oneof`_ ``payload``. text_payload (str): The log entry payload, represented as a Unicode string (UTF-8). + This field is a member of `oneof`_ ``payload``. json_payload (google.protobuf.struct_pb2.Struct): The log entry payload, represented as a structure that is expressed as a JSON object. + This field is a member of `oneof`_ ``payload``. timestamp (google.protobuf.timestamp_pb2.Timestamp): Optional. The time the event described by the log entry occurred. This time is used to compute the log entry's age diff --git a/google/cloud/logging_v2/types/logging.py b/google/cloud/logging_v2/types/logging.py index 6d64b9a91..8477c2a49 100644 --- a/google/cloud/logging_v2/types/logging.py +++ b/google/cloud/logging_v2/types/logging.py @@ -42,6 +42,7 @@ class DeleteLogRequest(proto.Message): r"""The parameters to DeleteLog. + Attributes: log_name (str): Required. The resource name of the log to delete: @@ -65,6 +66,7 @@ class DeleteLogRequest(proto.Message): class WriteLogEntriesRequest(proto.Message): r"""The parameters to WriteLogEntries. + Attributes: log_name (str): Optional. A default log resource name that is assigned to @@ -164,11 +166,13 @@ class WriteLogEntriesRequest(proto.Message): class WriteLogEntriesResponse(proto.Message): - r"""Result returned from WriteLogEntries. """ + r"""Result returned from WriteLogEntries. + """ class WriteLogEntriesPartialErrors(proto.Message): r"""Error details for WriteLogEntries with partial success. + Attributes: log_entry_errors (Sequence[google.cloud.logging_v2.types.WriteLogEntriesPartialErrors.LogEntryErrorsEntry]): When ``WriteLogEntriesRequest.partial_success`` is true, @@ -187,6 +191,7 @@ class WriteLogEntriesPartialErrors(proto.Message): class ListLogEntriesRequest(proto.Message): r"""The parameters to ``ListLogEntries``. + Attributes: resource_names (Sequence[str]): Required. Names of one or more parent resources from which @@ -249,6 +254,7 @@ class ListLogEntriesRequest(proto.Message): class ListLogEntriesResponse(proto.Message): r"""Result returned from ``ListLogEntries``. + Attributes: entries (Sequence[google.cloud.logging_v2.types.LogEntry]): A list of log entries. If ``entries`` is empty, @@ -281,6 +287,7 @@ def raw_page(self): class ListMonitoredResourceDescriptorsRequest(proto.Message): r"""The parameters to ListMonitoredResourceDescriptors + Attributes: page_size (int): Optional. The maximum number of results to return from this @@ -301,6 +308,7 @@ class ListMonitoredResourceDescriptorsRequest(proto.Message): class ListMonitoredResourceDescriptorsResponse(proto.Message): r"""Result returned from ListMonitoredResourceDescriptors. + Attributes: resource_descriptors (Sequence[google.api.monitored_resource_pb2.MonitoredResourceDescriptor]): A list of resource descriptors. @@ -325,6 +333,7 @@ def raw_page(self): class ListLogsRequest(proto.Message): r"""The parameters to ListLogs. + Attributes: parent (str): Required. The resource name that owns the logs: @@ -366,6 +375,7 @@ class ListLogsRequest(proto.Message): class ListLogsResponse(proto.Message): r"""Result returned from ListLogs. + Attributes: log_names (Sequence[str]): A list of log names. For example, @@ -388,6 +398,7 @@ def raw_page(self): class TailLogEntriesRequest(proto.Message): r"""The parameters to ``TailLogEntries``. + Attributes: resource_names (Sequence[str]): Required. Name of a parent resource from which to retrieve @@ -431,6 +442,7 @@ class TailLogEntriesRequest(proto.Message): class TailLogEntriesResponse(proto.Message): r"""Result returned from ``TailLogEntries``. + Attributes: entries (Sequence[google.cloud.logging_v2.types.LogEntry]): A list of log entries. Each response in the stream will @@ -450,6 +462,7 @@ class TailLogEntriesResponse(proto.Message): class SuppressionInfo(proto.Message): r"""Information about entries that were omitted from the session. + Attributes: reason (google.cloud.logging_v2.types.TailLogEntriesResponse.SuppressionInfo.Reason): The reason that entries were omitted from the diff --git a/google/cloud/logging_v2/types/logging_config.py b/google/cloud/logging_v2/types/logging_config.py index 9b6280731..0724911b9 100644 --- a/google/cloud/logging_v2/types/logging_config.py +++ b/google/cloud/logging_v2/types/logging_config.py @@ -69,6 +69,7 @@ class LifecycleState(proto.Enum): class LogBucket(proto.Message): r"""Describes a repository of logs. + Attributes: name (str): The resource name of the bucket. For example: @@ -114,6 +115,7 @@ class LogBucket(proto.Message): class LogView(proto.Message): r"""Describes a view over logs in a bucket. + Attributes: name (str): The resource name of the view. @@ -152,6 +154,9 @@ class LogSink(proto.Message): created within a project, organization, billing account, or folder. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: name (str): Required. The client-assigned sink identifier, unique within @@ -236,6 +241,7 @@ class LogSink(proto.Message): bigquery_options (google.cloud.logging_v2.types.BigQueryOptions): Optional. Options that affect sinks exporting data to BigQuery. + This field is a member of `oneof`_ ``options``. create_time (google.protobuf.timestamp_pb2.Timestamp): Output only. The creation timestamp of the sink. @@ -303,6 +309,7 @@ class BigQueryOptions(proto.Message): class ListBucketsRequest(proto.Message): r"""The parameters to ``ListBuckets``. + Attributes: parent (str): Required. The parent resource whose buckets are to be @@ -338,6 +345,7 @@ class ListBucketsRequest(proto.Message): class ListBucketsResponse(proto.Message): r"""The response from ListBuckets. + Attributes: buckets (Sequence[google.cloud.logging_v2.types.LogBucket]): A list of buckets. @@ -358,6 +366,7 @@ def raw_page(self): class CreateBucketRequest(proto.Message): r"""The parameters to ``CreateBucket``. + Attributes: parent (str): Required. The resource in which to create the bucket: @@ -386,6 +395,7 @@ class CreateBucketRequest(proto.Message): class UpdateBucketRequest(proto.Message): r"""The parameters to ``UpdateBucket``. + Attributes: name (str): Required. The full resource name of the bucket to update. @@ -425,6 +435,7 @@ class UpdateBucketRequest(proto.Message): class GetBucketRequest(proto.Message): r"""The parameters to ``GetBucket``. + Attributes: name (str): Required. The resource name of the bucket: @@ -445,6 +456,7 @@ class GetBucketRequest(proto.Message): class DeleteBucketRequest(proto.Message): r"""The parameters to ``DeleteBucket``. + Attributes: name (str): Required. The full resource name of the bucket to delete. @@ -465,6 +477,7 @@ class DeleteBucketRequest(proto.Message): class UndeleteBucketRequest(proto.Message): r"""The parameters to ``UndeleteBucket``. + Attributes: name (str): Required. The full resource name of the bucket to undelete. @@ -485,6 +498,7 @@ class UndeleteBucketRequest(proto.Message): class ListViewsRequest(proto.Message): r"""The parameters to ``ListViews``. + Attributes: parent (str): Required. The bucket whose views are to be listed: @@ -512,6 +526,7 @@ class ListViewsRequest(proto.Message): class ListViewsResponse(proto.Message): r"""The response from ListViews. + Attributes: views (Sequence[google.cloud.logging_v2.types.LogView]): A list of views. @@ -532,6 +547,7 @@ def raw_page(self): class CreateViewRequest(proto.Message): r"""The parameters to ``CreateView``. + Attributes: parent (str): Required. The bucket in which to create the view @@ -555,6 +571,7 @@ class CreateViewRequest(proto.Message): class UpdateViewRequest(proto.Message): r"""The parameters to ``UpdateView``. + Attributes: name (str): Required. The full resource name of the view to update @@ -588,6 +605,7 @@ class UpdateViewRequest(proto.Message): class GetViewRequest(proto.Message): r"""The parameters to ``GetView``. + Attributes: name (str): Required. The resource name of the policy: @@ -605,6 +623,7 @@ class GetViewRequest(proto.Message): class DeleteViewRequest(proto.Message): r"""The parameters to ``DeleteView``. + Attributes: name (str): Required. The full resource name of the view to delete: @@ -622,6 +641,7 @@ class DeleteViewRequest(proto.Message): class ListSinksRequest(proto.Message): r"""The parameters to ``ListSinks``. + Attributes: parent (str): Required. The parent resource whose sinks are to be listed: @@ -652,6 +672,7 @@ class ListSinksRequest(proto.Message): class ListSinksResponse(proto.Message): r"""Result returned from ``ListSinks``. + Attributes: sinks (Sequence[google.cloud.logging_v2.types.LogSink]): A list of sinks. @@ -672,6 +693,7 @@ def raw_page(self): class GetSinkRequest(proto.Message): r"""The parameters to ``GetSink``. + Attributes: sink_name (str): Required. The resource name of the sink: @@ -691,6 +713,7 @@ class GetSinkRequest(proto.Message): class CreateSinkRequest(proto.Message): r"""The parameters to ``CreateSink``. + Attributes: parent (str): Required. The resource in which to create the sink: @@ -731,6 +754,7 @@ class CreateSinkRequest(proto.Message): class UpdateSinkRequest(proto.Message): r"""The parameters to ``UpdateSink``. + Attributes: sink_name (str): Required. The full resource name of the sink to update, @@ -791,6 +815,7 @@ class UpdateSinkRequest(proto.Message): class DeleteSinkRequest(proto.Message): r"""The parameters to ``DeleteSink``. + Attributes: sink_name (str): Required. The full resource name of the sink to delete, @@ -865,6 +890,7 @@ class LogExclusion(proto.Message): class ListExclusionsRequest(proto.Message): r"""The parameters to ``ListExclusions``. + Attributes: parent (str): Required. The parent resource whose exclusions are to be @@ -896,6 +922,7 @@ class ListExclusionsRequest(proto.Message): class ListExclusionsResponse(proto.Message): r"""Result returned from ``ListExclusions``. + Attributes: exclusions (Sequence[google.cloud.logging_v2.types.LogExclusion]): A list of exclusions. @@ -916,6 +943,7 @@ def raw_page(self): class GetExclusionRequest(proto.Message): r"""The parameters to ``GetExclusion``. + Attributes: name (str): Required. The resource name of an existing exclusion: @@ -936,6 +964,7 @@ class GetExclusionRequest(proto.Message): class CreateExclusionRequest(proto.Message): r"""The parameters to ``CreateExclusion``. + Attributes: parent (str): Required. The parent resource in which to create the @@ -962,6 +991,7 @@ class CreateExclusionRequest(proto.Message): class UpdateExclusionRequest(proto.Message): r"""The parameters to ``UpdateExclusion``. + Attributes: name (str): Required. The resource name of the exclusion to update: @@ -1000,6 +1030,7 @@ class UpdateExclusionRequest(proto.Message): class DeleteExclusionRequest(proto.Message): r"""The parameters to ``DeleteExclusion``. + Attributes: name (str): Required. The resource name of an existing exclusion to diff --git a/google/cloud/logging_v2/types/logging_metrics.py b/google/cloud/logging_v2/types/logging_metrics.py index 4b39650f2..26d855680 100644 --- a/google/cloud/logging_v2/types/logging_metrics.py +++ b/google/cloud/logging_v2/types/logging_metrics.py @@ -187,6 +187,7 @@ class ApiVersion(proto.Enum): class ListLogMetricsRequest(proto.Message): r"""The parameters to ListLogMetrics. + Attributes: parent (str): Required. The name of the project containing the metrics: @@ -214,6 +215,7 @@ class ListLogMetricsRequest(proto.Message): class ListLogMetricsResponse(proto.Message): r"""Result returned from ListLogMetrics. + Attributes: metrics (Sequence[google.cloud.logging_v2.types.LogMetric]): A list of logs-based metrics. @@ -234,6 +236,7 @@ def raw_page(self): class GetLogMetricRequest(proto.Message): r"""The parameters to GetLogMetric. + Attributes: metric_name (str): Required. The resource name of the desired metric: @@ -248,6 +251,7 @@ class GetLogMetricRequest(proto.Message): class CreateLogMetricRequest(proto.Message): r"""The parameters to CreateLogMetric. + Attributes: parent (str): Required. The resource name of the project in which to @@ -269,6 +273,7 @@ class CreateLogMetricRequest(proto.Message): class UpdateLogMetricRequest(proto.Message): r"""The parameters to UpdateLogMetric. + Attributes: metric_name (str): Required. The resource name of the metric to update: @@ -291,6 +296,7 @@ class UpdateLogMetricRequest(proto.Message): class DeleteLogMetricRequest(proto.Message): r"""The parameters to DeleteLogMetric. + Attributes: metric_name (str): Required. The resource name of the metric to delete: diff --git a/noxfile.py b/noxfile.py index 9e49bd0d9..96ef7ee7e 100644 --- a/noxfile.py +++ b/noxfile.py @@ -29,7 +29,7 @@ DEFAULT_PYTHON_VERSION = "3.8" SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"] -UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] +UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10"] CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -84,18 +84,18 @@ def default(session): constraints_path = str( CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" ) - session.install("asyncmock", "pytest-asyncio", "-c", constraints_path) - session.install( "mock", + "asyncmock", "pytest", "pytest-cov", - "flask", - "webob", - "django", + "pytest-asyncio", "-c", constraints_path, ) + session.install("flask", "-c", constraints_path) + session.install("webob", "-c", constraints_path) + session.install("django", "-c", constraints_path) session.install("-e", ".", "-c", constraints_path) @@ -104,7 +104,7 @@ def default(session): "py.test", "--quiet", f"--junitxml=unit_{session.python}_sponge_log.xml", - "--cov=google/cloud", + "--cov=google", "--cov=tests/unit", "--cov-append", "--cov-config=.coveragerc", diff --git a/owlbot.py b/owlbot.py index b7cbcae4f..ad8e32d4c 100644 --- a/owlbot.py +++ b/owlbot.py @@ -92,13 +92,6 @@ }""" ) - -# -------------------------------------------------------------------------- -# Samples templates -# -------------------------------------------------------------------------- - -python.py_samples() - # -------------------------------------------------------------------------- # Samples templates # -------------------------------------------------------------------------- @@ -106,3 +99,4 @@ python.py_samples() s.shell.run(["nox", "-s", "blacken"], hide_output=False) + diff --git a/renovate.json b/renovate.json index 9d2f2512a..bcd0e005a 100644 --- a/renovate.json +++ b/renovate.json @@ -1,6 +1,9 @@ { "extends": [ - "config:base", ":preserveSemverRanges" + "config:base", + "group:all", + ":preserveSemverRanges", + ":disableDependencyDashboard" ], "ignorePaths": [".pre-commit-config.yaml"], "pip_requirements": { diff --git a/samples/snippets/handler.py b/samples/snippets/handler.py index 0a708c138..49d257898 100644 --- a/samples/snippets/handler.py +++ b/samples/snippets/handler.py @@ -28,7 +28,6 @@ def use_logging_handler(): # you're running in and integrates the handler with the # Python logging module. By default this captures all logs # at INFO level and higher - client.get_default_handler() client.setup_logging() # [END logging_handler_setup] diff --git a/samples/snippets/noxfile.py b/samples/snippets/noxfile.py index 6a8ccdae2..93a9122cc 100644 --- a/samples/snippets/noxfile.py +++ b/samples/snippets/noxfile.py @@ -39,17 +39,15 @@ TEST_CONFIG = { # You can opt out from the test for specific Python versions. - 'ignored_versions': ["2.7"], - + "ignored_versions": [], # Old samples are opted out of enforcing Python type hints # All new samples should feature them - 'enforce_type_hints': False, - + "enforce_type_hints": False, # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string # to use your own Cloud project. - 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', # If you need to use a specific version of pip, # change pip_version_override to the string representation @@ -57,13 +55,13 @@ "pip_version_override": None, # A dictionary you want to inject into your test. Don't put any # secrets here. These values will override predefined values. - 'envs': {}, + "envs": {}, } try: # Ensure we can import noxfile_config in the project's directory. - sys.path.append('.') + sys.path.append(".") from noxfile_config import TEST_CONFIG_OVERRIDE except ImportError as e: print("No user noxfile_config found: detail: {}".format(e)) @@ -78,25 +76,32 @@ def get_pytest_env_vars() -> Dict[str, str]: ret = {} # Override the GCLOUD_PROJECT and the alias. - env_key = TEST_CONFIG['gcloud_project_env'] + env_key = TEST_CONFIG["gcloud_project_env"] # This should error out if not set. - ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] # Apply user supplied envs. - ret.update(TEST_CONFIG['envs']) + ret.update(TEST_CONFIG["envs"]) return ret # DO NOT EDIT - automatically generated. -# All versions used to tested samples. -ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"] +# All versions used to test samples. +ALL_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10"] # Any default versions that should be ignored. -IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) -INSTALL_LIBRARY_FROM_SOURCE = bool(os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False)) +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + # # Style Checks # @@ -141,7 +146,7 @@ def _determine_local_import_names(start_dir: str) -> List[str]: @nox.session def lint(session: nox.sessions.Session) -> None: - if not TEST_CONFIG['enforce_type_hints']: + if not TEST_CONFIG["enforce_type_hints"]: session.install("flake8", "flake8-import-order") else: session.install("flake8", "flake8-import-order", "flake8-annotations") @@ -150,9 +155,11 @@ def lint(session: nox.sessions.Session) -> None: args = FLAKE8_COMMON_ARGS + [ "--application-import-names", ",".join(local_names), - "." + ".", ] session.run("flake8", *args) + + # # Black # @@ -165,6 +172,7 @@ def blacken(session: nox.sessions.Session) -> None: session.run("black", *python_files) + # # Sample Tests # @@ -173,7 +181,9 @@ def blacken(session: nox.sessions.Session) -> None: PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] -def _session_tests(session: nox.sessions.Session, post_install: Callable = None) -> None: +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: if TEST_CONFIG["pip_version_override"]: pip_version = TEST_CONFIG["pip_version_override"] session.install(f"pip=={pip_version}") @@ -203,7 +213,7 @@ def _session_tests(session: nox.sessions.Session, post_install: Callable = None) # on travis where slow and flaky tests are excluded. # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html success_codes=[0, 5], - env=get_pytest_env_vars() + env=get_pytest_env_vars(), ) @@ -213,9 +223,9 @@ def py(session: nox.sessions.Session) -> None: if session.python in TESTED_VERSIONS: _session_tests(session) else: - session.skip("SKIPPED: {} tests are disabled for this sample.".format( - session.python - )) + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) # diff --git a/samples/snippets/requirements-test.txt b/samples/snippets/requirements-test.txt index 0db5cc446..fbe6c1c5c 100644 --- a/samples/snippets/requirements-test.txt +++ b/samples/snippets/requirements-test.txt @@ -1,2 +1,2 @@ backoff==1.11.1 -pytest==6.2.4 +pytest==6.2.5 diff --git a/samples/snippets/requirements.txt b/samples/snippets/requirements.txt index 1f7eb19dd..c3c03d970 100644 --- a/samples/snippets/requirements.txt +++ b/samples/snippets/requirements.txt @@ -1,4 +1,4 @@ -google-cloud-logging==2.5.0 -google-cloud-bigquery==2.23.1 -google-cloud-storage==1.41.1 -google-cloud-pubsub==2.7.0 +google-cloud-logging==2.6.0 +google-cloud-bigquery==2.28.1 +google-cloud-storage==1.42.3 +google-cloud-pubsub==2.8.0 diff --git a/samples/snippets/usage_guide.py b/samples/snippets/usage_guide.py index c931ed167..e519c75c1 100644 --- a/samples/snippets/usage_guide.py +++ b/samples/snippets/usage_guide.py @@ -71,6 +71,33 @@ def client_list_entries(client, to_delete): # pylint: disable=unused-argument # [END client_list_entries_order_by] break + # [START logging_list_gke_audit_logs] + import google.cloud.logging + from datetime import datetime, timedelta, timezone + import os + + # pull your project id from an environment variable + project_id = os.environ["GOOGLE_CLOUD_PROJECT"] + # construct a date object representing yesterday + yesterday = datetime.now(timezone.utc) - timedelta(days=1) + # Cloud Logging expects a timestamp in RFC3339 UTC "Zulu" format + # https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry + time_format = "%Y-%m-%dT%H:%M:%S.%f%z" + # build a filter that returns GKE Admin Activity audit Logs from + # the past 24 hours + # https://cloud.google.com/kubernetes-engine/docs/how-to/audit-logging + filter_str = ( + f'logName="projects/{project_id}/logs/cloudaudit.googleapis.com%2Factivity"' + f' AND resource.type="k8s_cluster"' + f' AND timestamp>="{yesterday.strftime(time_format)}"' + ) + # query and print all matching logs + client = google.cloud.logging.Client() + for entry in client.list_entries(filter_=filter_str): + print(entry) + # [END logging_list_gke_audit_logs] + break # we don't really need to print them all + @snippet def logger_usage(client, to_delete): diff --git a/scripts/readme-gen/templates/install_deps.tmpl.rst b/scripts/readme-gen/templates/install_deps.tmpl.rst index a0406dba8..275d64989 100644 --- a/scripts/readme-gen/templates/install_deps.tmpl.rst +++ b/scripts/readme-gen/templates/install_deps.tmpl.rst @@ -12,7 +12,7 @@ Install Dependencies .. _Python Development Environment Setup Guide: https://cloud.google.com/python/setup -#. Create a virtualenv. Samples are compatible with Python 2.7 and 3.4+. +#. Create a virtualenv. Samples are compatible with Python 3.6+. .. code-block:: bash diff --git a/setup.py b/setup.py index 6a9ed8a59..b31ae8f78 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ name = "google-cloud-logging" description = "Stackdriver Logging API client library" -version = "2.6.0" +version = "2.7.0" # Should be one of: # 'Development Status :: 3 - Alpha' # 'Development Status :: 4 - Beta' @@ -33,14 +33,14 @@ # Until this issue is closed # https://github.com/googleapis/google-cloud-python/issues/10566 "google-api-core[grpc] >= 1.26.0, <3.0.0dev", - "google-cloud-appengine-logging >= 0.1.0, < 1.0.0dev", + "google-cloud-appengine-logging>=0.1.0, <2.0.0dev", "google-cloud-audit-log >= 0.1.0, < 1.0.0dev", # NOTE: Maintainers, please do not require google-api-core>=2.x.x # Until this issue is closed # https://github.com/googleapis/google-cloud-python/issues/10566 "google-cloud-core >= 1.4.1, <3.0.0dev", - "proto-plus >= 1.11.0", - "packaging >= 14.3", + "grpc-google-iam-v1 >= 0.12.3, < 0.13dev", + "proto-plus >= 1.15.0", ] extras = {} diff --git a/testing/constraints-3.6.txt b/testing/constraints-3.6.txt index 7e089b8b4..250c505ff 100644 --- a/testing/constraints-3.6.txt +++ b/testing/constraints-3.6.txt @@ -5,7 +5,6 @@ # # e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev", # Then this file should have foo==1.14.0 -google-api-core==1.26.0 +google-api-core==1.28.0 google-cloud-core==1.4.1 -proto-plus==1.11.0 -packaging==14.3 +proto-plus==1.15.0 diff --git a/tests/environment b/tests/environment index a0af8d102..dc8506605 160000 --- a/tests/environment +++ b/tests/environment @@ -1 +1 @@ -Subproject commit a0af8d102a3c711cdff0dd12e01c8bfd357b7a83 +Subproject commit dc85066053b8dc2246c8b72f93a5b97f92885eb2 diff --git a/tests/system/test_system.py b/tests/system/test_system.py index 81de866ee..532eea96b 100644 --- a/tests/system/test_system.py +++ b/tests/system/test_system.py @@ -260,6 +260,39 @@ def test_list_entry_with_requestlog(self): protobuf_entry.to_api_repr()["protoPayload"]["@type"], type_url ) + def test_list_entry_with_auditdata(self): + """ + Test emitting and listing logs containing a google.iam.v1.logging.AuditData proto message + """ + from google.protobuf import descriptor_pool + from google.cloud.logging_v2 import entries + + pool = descriptor_pool.Default() + type_name = "google.iam.v1.logging.AuditData" + type_url = "type.googleapis.com/" + type_name + # Make sure the descriptor is known in the registry. + # Raises KeyError if unknown + pool.FindMessageTypeByName(type_name) + + # create log + req_dict = {"@type": type_url, "policyDelta": {}} + req_struct = self._dict_to_struct(req_dict) + + logger = Config.CLIENT.logger(f"auditdata-proto-{uuid.uuid1()}") + logger.log_proto(req_struct) + + # retrieve log + retry = RetryErrors((TooManyRequests, StopIteration), max_tries=8) + protobuf_entry = retry(lambda: next(logger.list_entries()))() + + self.assertIsInstance(protobuf_entry, entries.ProtobufEntry) + self.assertIsNone(protobuf_entry.payload_pb) + self.assertIsInstance(protobuf_entry.payload_json, dict) + self.assertEqual(protobuf_entry.payload_json["@type"], type_url) + self.assertEqual( + protobuf_entry.to_api_repr()["protoPayload"]["@type"], type_url + ) + def test_log_text(self): TEXT_PAYLOAD = "System test: test_log_text" logger = Config.CLIENT.logger(self._logger_name("log_text")) diff --git a/tests/unit/gapic/logging_v2/test_config_service_v2.py b/tests/unit/gapic/logging_v2/test_config_service_v2.py index 12a5cf896..0d96a08fc 100644 --- a/tests/unit/gapic/logging_v2/test_config_service_v2.py +++ b/tests/unit/gapic/logging_v2/test_config_service_v2.py @@ -15,7 +15,6 @@ # import os import mock -import packaging.version import grpc from grpc.experimental import aio @@ -29,6 +28,7 @@ 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.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.logging_v2.services.config_service_v2 import ( @@ -37,9 +37,6 @@ from google.cloud.logging_v2.services.config_service_v2 import ConfigServiceV2Client from google.cloud.logging_v2.services.config_service_v2 import pagers from google.cloud.logging_v2.services.config_service_v2 import transports -from google.cloud.logging_v2.services.config_service_v2.transports.base import ( - _GOOGLE_AUTH_VERSION, -) from google.cloud.logging_v2.types import logging_config from google.oauth2 import service_account from google.protobuf import field_mask_pb2 # type: ignore @@ -47,20 +44,6 @@ import google.auth -# TODO(busunkim): Once google-auth >= 1.25.0 is required transitively -# through google-api-core: -# - Delete the auth "less than" test cases -# - Delete these pytest markers (Make the "greater than or equal to" tests the default). -requires_google_auth_lt_1_25_0 = pytest.mark.skipif( - packaging.version.parse(_GOOGLE_AUTH_VERSION) >= packaging.version.parse("1.25.0"), - reason="This test requires google-auth < 1.25.0", -) -requires_google_auth_gte_1_25_0 = pytest.mark.skipif( - packaging.version.parse(_GOOGLE_AUTH_VERSION) < packaging.version.parse("1.25.0"), - reason="This test requires google-auth >= 1.25.0", -) - - def client_cert_source_callback(): return b"cert bytes", b"key bytes" @@ -217,7 +200,7 @@ def test_config_service_v2_client_client_options( 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(client_options=options) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -234,7 +217,7 @@ def test_config_service_v2_client_client_options( 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() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -251,7 +234,7 @@ def test_config_service_v2_client_client_options( 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() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -280,7 +263,7 @@ def test_config_service_v2_client_client_options( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -349,7 +332,7 @@ def test_config_service_v2_client_mtls_env_auto( ) with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(client_options=options) + client = client_class(transport=transport_name, client_options=options) if use_client_cert_env == "false": expected_client_cert_source = None @@ -391,7 +374,7 @@ def test_config_service_v2_client_mtls_env_auto( expected_client_cert_source = client_cert_source_callback patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -413,7 +396,7 @@ def test_config_service_v2_client_mtls_env_auto( return_value=False, ): patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -444,7 +427,7 @@ def test_config_service_v2_client_client_options_scopes( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -475,7 +458,7 @@ def test_config_service_v2_client_client_options_credentials_file( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file="credentials.json", @@ -5437,8 +5420,10 @@ def test_config_service_v2_base_transport(): with pytest.raises(NotImplementedError): getattr(transport, method)(request=object()) + with pytest.raises(NotImplementedError): + transport.close() + -@requires_google_auth_gte_1_25_0 def test_config_service_v2_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( @@ -5464,31 +5449,6 @@ def test_config_service_v2_base_transport_with_credentials_file(): ) -@requires_google_auth_lt_1_25_0 -def test_config_service_v2_base_transport_with_credentials_file_old_google_auth(): - # Instantiate the base transport with a credentials file - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch( - "google.cloud.logging_v2.services.config_service_v2.transports.ConfigServiceV2Transport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ConfigServiceV2Transport( - credentials_file="credentials.json", quota_project_id="octopus", - ) - load_creds.assert_called_once_with( - "credentials.json", - scopes=( - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/logging.admin", - "https://www.googleapis.com/auth/logging.read", - ), - quota_project_id="octopus", - ) - - def test_config_service_v2_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( @@ -5500,7 +5460,6 @@ def test_config_service_v2_base_transport_with_adc(): adc.assert_called_once() -@requires_google_auth_gte_1_25_0 def test_config_service_v2_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(google.auth, "default", autospec=True) as adc: @@ -5518,23 +5477,6 @@ def test_config_service_v2_auth_adc(): ) -@requires_google_auth_lt_1_25_0 -def test_config_service_v2_auth_adc_old_google_auth(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - ConfigServiceV2Client() - adc.assert_called_once_with( - scopes=( - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/logging.admin", - "https://www.googleapis.com/auth/logging.read", - ), - quota_project_id=None, - ) - - @pytest.mark.parametrize( "transport_class", [ @@ -5542,7 +5484,6 @@ def test_config_service_v2_auth_adc_old_google_auth(): transports.ConfigServiceV2GrpcAsyncIOTransport, ], ) -@requires_google_auth_gte_1_25_0 def test_config_service_v2_transport_auth_adc(transport_class): # If credentials and host are not provided, the transport class should use # ADC credentials. @@ -5561,31 +5502,6 @@ def test_config_service_v2_transport_auth_adc(transport_class): ) -@pytest.mark.parametrize( - "transport_class", - [ - transports.ConfigServiceV2GrpcTransport, - transports.ConfigServiceV2GrpcAsyncIOTransport, - ], -) -@requires_google_auth_lt_1_25_0 -def test_config_service_v2_transport_auth_adc_old_google_auth(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus") - adc.assert_called_once_with( - scopes=( - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/logging.admin", - "https://www.googleapis.com/auth/logging.read", - ), - quota_project_id="octopus", - ) - - @pytest.mark.parametrize( "transport_class,grpc_helpers", [ @@ -6040,3 +5956,49 @@ def test_client_withDEFAULT_CLIENT_INFO(): credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = ConfigServiceV2AsyncClient( + credentials=ga_credentials.AnonymousCredentials(), 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(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ConfigServiceV2Client( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = ConfigServiceV2Client( + 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() diff --git a/tests/unit/gapic/logging_v2/test_logging_service_v2.py b/tests/unit/gapic/logging_v2/test_logging_service_v2.py index 1bf1ac26f..5d6021f9a 100644 --- a/tests/unit/gapic/logging_v2/test_logging_service_v2.py +++ b/tests/unit/gapic/logging_v2/test_logging_service_v2.py @@ -15,7 +15,6 @@ # import os import mock -import packaging.version import grpc from grpc.experimental import aio @@ -30,6 +29,7 @@ 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.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.logging_v2.services.logging_service_v2 import ( @@ -38,9 +38,6 @@ from google.cloud.logging_v2.services.logging_service_v2 import LoggingServiceV2Client from google.cloud.logging_v2.services.logging_service_v2 import pagers from google.cloud.logging_v2.services.logging_service_v2 import transports -from google.cloud.logging_v2.services.logging_service_v2.transports.base import ( - _GOOGLE_AUTH_VERSION, -) from google.cloud.logging_v2.types import log_entry from google.cloud.logging_v2.types import logging from google.logging.type import http_request_pb2 # type: ignore @@ -53,20 +50,6 @@ import google.auth -# TODO(busunkim): Once google-auth >= 1.25.0 is required transitively -# through google-api-core: -# - Delete the auth "less than" test cases -# - Delete these pytest markers (Make the "greater than or equal to" tests the default). -requires_google_auth_lt_1_25_0 = pytest.mark.skipif( - packaging.version.parse(_GOOGLE_AUTH_VERSION) >= packaging.version.parse("1.25.0"), - reason="This test requires google-auth < 1.25.0", -) -requires_google_auth_gte_1_25_0 = pytest.mark.skipif( - packaging.version.parse(_GOOGLE_AUTH_VERSION) < packaging.version.parse("1.25.0"), - reason="This test requires google-auth >= 1.25.0", -) - - def client_cert_source_callback(): return b"cert bytes", b"key bytes" @@ -224,7 +207,7 @@ def test_logging_service_v2_client_client_options( 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(client_options=options) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -241,7 +224,7 @@ def test_logging_service_v2_client_client_options( 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() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -258,7 +241,7 @@ def test_logging_service_v2_client_client_options( 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() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -287,7 +270,7 @@ def test_logging_service_v2_client_client_options( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -356,7 +339,7 @@ def test_logging_service_v2_client_mtls_env_auto( ) with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(client_options=options) + client = client_class(transport=transport_name, client_options=options) if use_client_cert_env == "false": expected_client_cert_source = None @@ -398,7 +381,7 @@ def test_logging_service_v2_client_mtls_env_auto( expected_client_cert_source = client_cert_source_callback patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -420,7 +403,7 @@ def test_logging_service_v2_client_mtls_env_auto( return_value=False, ): patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -451,7 +434,7 @@ def test_logging_service_v2_client_client_options_scopes( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -482,7 +465,7 @@ def test_logging_service_v2_client_client_options_credentials_file( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file="credentials.json", @@ -1969,8 +1952,10 @@ def test_logging_service_v2_base_transport(): with pytest.raises(NotImplementedError): getattr(transport, method)(request=object()) + with pytest.raises(NotImplementedError): + transport.close() + -@requires_google_auth_gte_1_25_0 def test_logging_service_v2_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( @@ -1997,32 +1982,6 @@ def test_logging_service_v2_base_transport_with_credentials_file(): ) -@requires_google_auth_lt_1_25_0 -def test_logging_service_v2_base_transport_with_credentials_file_old_google_auth(): - # Instantiate the base transport with a credentials file - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch( - "google.cloud.logging_v2.services.logging_service_v2.transports.LoggingServiceV2Transport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.LoggingServiceV2Transport( - credentials_file="credentials.json", quota_project_id="octopus", - ) - load_creds.assert_called_once_with( - "credentials.json", - scopes=( - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/logging.admin", - "https://www.googleapis.com/auth/logging.read", - "https://www.googleapis.com/auth/logging.write", - ), - quota_project_id="octopus", - ) - - def test_logging_service_v2_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( @@ -2034,7 +1993,6 @@ def test_logging_service_v2_base_transport_with_adc(): adc.assert_called_once() -@requires_google_auth_gte_1_25_0 def test_logging_service_v2_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(google.auth, "default", autospec=True) as adc: @@ -2053,24 +2011,6 @@ def test_logging_service_v2_auth_adc(): ) -@requires_google_auth_lt_1_25_0 -def test_logging_service_v2_auth_adc_old_google_auth(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - LoggingServiceV2Client() - adc.assert_called_once_with( - scopes=( - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/logging.admin", - "https://www.googleapis.com/auth/logging.read", - "https://www.googleapis.com/auth/logging.write", - ), - quota_project_id=None, - ) - - @pytest.mark.parametrize( "transport_class", [ @@ -2078,7 +2018,6 @@ def test_logging_service_v2_auth_adc_old_google_auth(): transports.LoggingServiceV2GrpcAsyncIOTransport, ], ) -@requires_google_auth_gte_1_25_0 def test_logging_service_v2_transport_auth_adc(transport_class): # If credentials and host are not provided, the transport class should use # ADC credentials. @@ -2098,32 +2037,6 @@ def test_logging_service_v2_transport_auth_adc(transport_class): ) -@pytest.mark.parametrize( - "transport_class", - [ - transports.LoggingServiceV2GrpcTransport, - transports.LoggingServiceV2GrpcAsyncIOTransport, - ], -) -@requires_google_auth_lt_1_25_0 -def test_logging_service_v2_transport_auth_adc_old_google_auth(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus") - adc.assert_called_once_with( - scopes=( - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/logging.admin", - "https://www.googleapis.com/auth/logging.read", - "https://www.googleapis.com/auth/logging.write", - ), - quota_project_id="octopus", - ) - - @pytest.mark.parametrize( "transport_class,grpc_helpers", [ @@ -2489,3 +2402,49 @@ def test_client_withDEFAULT_CLIENT_INFO(): credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = LoggingServiceV2AsyncClient( + credentials=ga_credentials.AnonymousCredentials(), 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(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = LoggingServiceV2Client( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = LoggingServiceV2Client( + 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() diff --git a/tests/unit/gapic/logging_v2/test_metrics_service_v2.py b/tests/unit/gapic/logging_v2/test_metrics_service_v2.py index 7455f075e..9c14746d0 100644 --- a/tests/unit/gapic/logging_v2/test_metrics_service_v2.py +++ b/tests/unit/gapic/logging_v2/test_metrics_service_v2.py @@ -15,7 +15,6 @@ # import os import mock -import packaging.version import grpc from grpc.experimental import aio @@ -33,6 +32,7 @@ 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.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.logging_v2.services.metrics_service_v2 import ( @@ -41,9 +41,6 @@ from google.cloud.logging_v2.services.metrics_service_v2 import MetricsServiceV2Client from google.cloud.logging_v2.services.metrics_service_v2 import pagers from google.cloud.logging_v2.services.metrics_service_v2 import transports -from google.cloud.logging_v2.services.metrics_service_v2.transports.base import ( - _GOOGLE_AUTH_VERSION, -) from google.cloud.logging_v2.types import logging_metrics from google.oauth2 import service_account from google.protobuf import duration_pb2 # type: ignore @@ -51,20 +48,6 @@ import google.auth -# TODO(busunkim): Once google-auth >= 1.25.0 is required transitively -# through google-api-core: -# - Delete the auth "less than" test cases -# - Delete these pytest markers (Make the "greater than or equal to" tests the default). -requires_google_auth_lt_1_25_0 = pytest.mark.skipif( - packaging.version.parse(_GOOGLE_AUTH_VERSION) >= packaging.version.parse("1.25.0"), - reason="This test requires google-auth < 1.25.0", -) -requires_google_auth_gte_1_25_0 = pytest.mark.skipif( - packaging.version.parse(_GOOGLE_AUTH_VERSION) < packaging.version.parse("1.25.0"), - reason="This test requires google-auth >= 1.25.0", -) - - def client_cert_source_callback(): return b"cert bytes", b"key bytes" @@ -222,7 +205,7 @@ def test_metrics_service_v2_client_client_options( 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(client_options=options) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -239,7 +222,7 @@ def test_metrics_service_v2_client_client_options( 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() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -256,7 +239,7 @@ def test_metrics_service_v2_client_client_options( 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() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -285,7 +268,7 @@ def test_metrics_service_v2_client_client_options( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -354,7 +337,7 @@ def test_metrics_service_v2_client_mtls_env_auto( ) with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(client_options=options) + client = client_class(transport=transport_name, client_options=options) if use_client_cert_env == "false": expected_client_cert_source = None @@ -396,7 +379,7 @@ def test_metrics_service_v2_client_mtls_env_auto( expected_client_cert_source = client_cert_source_callback patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -418,7 +401,7 @@ def test_metrics_service_v2_client_mtls_env_auto( return_value=False, ): patched.return_value = None - client = client_class() + client = client_class(transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -449,7 +432,7 @@ def test_metrics_service_v2_client_client_options_scopes( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -480,7 +463,7 @@ def test_metrics_service_v2_client_client_options_credentials_file( 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) + client = client_class(transport=transport_name, client_options=options) patched.assert_called_once_with( credentials=None, credentials_file="credentials.json", @@ -1892,8 +1875,10 @@ def test_metrics_service_v2_base_transport(): with pytest.raises(NotImplementedError): getattr(transport, method)(request=object()) + with pytest.raises(NotImplementedError): + transport.close() + -@requires_google_auth_gte_1_25_0 def test_metrics_service_v2_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( @@ -1920,32 +1905,6 @@ def test_metrics_service_v2_base_transport_with_credentials_file(): ) -@requires_google_auth_lt_1_25_0 -def test_metrics_service_v2_base_transport_with_credentials_file_old_google_auth(): - # Instantiate the base transport with a credentials file - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch( - "google.cloud.logging_v2.services.metrics_service_v2.transports.MetricsServiceV2Transport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.MetricsServiceV2Transport( - credentials_file="credentials.json", quota_project_id="octopus", - ) - load_creds.assert_called_once_with( - "credentials.json", - scopes=( - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/logging.admin", - "https://www.googleapis.com/auth/logging.read", - "https://www.googleapis.com/auth/logging.write", - ), - quota_project_id="octopus", - ) - - def test_metrics_service_v2_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( @@ -1957,7 +1916,6 @@ def test_metrics_service_v2_base_transport_with_adc(): adc.assert_called_once() -@requires_google_auth_gte_1_25_0 def test_metrics_service_v2_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(google.auth, "default", autospec=True) as adc: @@ -1976,24 +1934,6 @@ def test_metrics_service_v2_auth_adc(): ) -@requires_google_auth_lt_1_25_0 -def test_metrics_service_v2_auth_adc_old_google_auth(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - MetricsServiceV2Client() - adc.assert_called_once_with( - scopes=( - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/logging.admin", - "https://www.googleapis.com/auth/logging.read", - "https://www.googleapis.com/auth/logging.write", - ), - quota_project_id=None, - ) - - @pytest.mark.parametrize( "transport_class", [ @@ -2001,7 +1941,6 @@ def test_metrics_service_v2_auth_adc_old_google_auth(): transports.MetricsServiceV2GrpcAsyncIOTransport, ], ) -@requires_google_auth_gte_1_25_0 def test_metrics_service_v2_transport_auth_adc(transport_class): # If credentials and host are not provided, the transport class should use # ADC credentials. @@ -2021,32 +1960,6 @@ def test_metrics_service_v2_transport_auth_adc(transport_class): ) -@pytest.mark.parametrize( - "transport_class", - [ - transports.MetricsServiceV2GrpcTransport, - transports.MetricsServiceV2GrpcAsyncIOTransport, - ], -) -@requires_google_auth_lt_1_25_0 -def test_metrics_service_v2_transport_auth_adc_old_google_auth(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus") - adc.assert_called_once_with( - scopes=( - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - "https://www.googleapis.com/auth/logging.admin", - "https://www.googleapis.com/auth/logging.read", - "https://www.googleapis.com/auth/logging.write", - ), - quota_project_id="octopus", - ) - - @pytest.mark.parametrize( "transport_class,grpc_helpers", [ @@ -2414,3 +2327,49 @@ def test_client_withDEFAULT_CLIENT_INFO(): credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = MetricsServiceV2AsyncClient( + credentials=ga_credentials.AnonymousCredentials(), 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(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = MetricsServiceV2Client( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = MetricsServiceV2Client( + 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() diff --git a/tests/unit/handlers/test_structured_log.py b/tests/unit/handlers/test_structured_log.py index 3d1c11ab0..271a68189 100644 --- a/tests/unit/handlers/test_structured_log.py +++ b/tests/unit/handlers/test_structured_log.py @@ -119,6 +119,24 @@ def test_format_with_quotes(self): result = handler.format(record) self.assertIn(expected_result, result) + def test_format_with_exception(self): + """ + When logging a message with an exception, the stack trace should not be appended + """ + import logging + import json + + handler = self._make_one() + exception_tuple = (Exception, Exception(), None) + message = "test" + record = logging.LogRecord( + None, logging.INFO, None, None, message, None, exception_tuple + ) + record.created = None + handler.filter(record) + result = json.loads(handler.format(record)) + self.assertEqual(result["message"], f"{message}\nException") + def test_format_with_line_break(self): """ When logging a message containing \n, it should be properly escaped diff --git a/tests/unit/handlers/transports/test_background_thread.py b/tests/unit/handlers/transports/test_background_thread.py index 5410c5f10..1666cd74b 100644 --- a/tests/unit/handlers/transports/test_background_thread.py +++ b/tests/unit/handlers/transports/test_background_thread.py @@ -14,10 +14,10 @@ import time import logging +import queue import unittest import mock -from six.moves import queue class TestBackgroundThreadHandler(unittest.TestCase): @@ -379,7 +379,6 @@ def test__thread_main_max_latency(self, time): # _get_many invokes queue.get() followed by queue._get(). It fails # the "change detector" test in that way. However, this is still a # useful test to verify the queue timeout is appropriately calculated. - from six.moves import queue from google.cloud.logging_v2.handlers.transports import background_thread # Use monotonically increasing time.