diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 2567653c..39ad3cec 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,3 +1,16 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - digest: sha256:87eee22d276554e4e52863ec9b1cb6a7245815dfae20439712bf644348215a5a + digest: sha256:d22cd2ddce65fdac6986f115563faf2fc81482b09dfbea83ac2808c92ecfdff0 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1aad53aa..23c835c8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -3,9 +3,10 @@ # # For syntax help see: # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax +# Note: This file is autogenerated. To make changes to the codeowner team, please update .repo-metadata.json. -# The @googleapis/yoshi-python is the default owner for changes in this repo -* @googleapis/yoshi-python +# @googleapis/yoshi-python @googleapis/api-iot are the default owners for changes in this repo +* @googleapis/yoshi-python @googleapis/api-iot - -/samples/**/*.py @gcseh @googleapis/api-iot @googleapis/python-samples-owners \ No newline at end of file +# @googleapis/python-samples-reviewers @googleapis/api-iot are the default owners for samples changes +/samples/ @googleapis/python-samples-reviewers @googleapis/api-iot diff --git a/.github/release-please.yml b/.github/release-please.yml index 4507ad05..466597e5 100644 --- a/.github/release-please.yml +++ b/.github/release-please.yml @@ -1 +1,2 @@ releaseType: python +handleGHRelease: true diff --git a/.github/release-trigger.yml b/.github/release-trigger.yml new file mode 100644 index 00000000..d4ca9418 --- /dev/null +++ b/.github/release-trigger.yml @@ -0,0 +1 @@ +enabled: true diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index 3e98ae70..37438d33 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -10,6 +10,5 @@ branchProtectionRules: - 'Kokoro' - 'cla/google' - 'Samples - Lint' - - 'Samples - Python 3.6' - 'Samples - Python 3.7' - 'Samples - Python 3.8' diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..f7b8344c --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,38 @@ +on: + pull_request: + branches: + - main +name: docs +jobs: + docs: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: "3.10" + - name: Install nox + run: | + python -m pip install --upgrade setuptools pip wheel + python -m pip install nox + - name: Run docs + run: | + nox -s docs + docfx: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: "3.10" + - name: Install nox + run: | + python -m pip install --upgrade setuptools pip wheel + python -m pip install nox + - name: Run docfx + run: | + nox -s docfx diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..1e8b05c3 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,25 @@ +on: + pull_request: + branches: + - main +name: lint +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: "3.10" + - name: Install nox + run: | + python -m pip install --upgrade setuptools pip wheel + python -m pip install nox + - name: Run lint + run: | + nox -s lint + - name: Run lint_setup_py + run: | + nox -s lint_setup_py diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml new file mode 100644 index 00000000..074ee250 --- /dev/null +++ b/.github/workflows/unittest.yml @@ -0,0 +1,57 @@ +on: + pull_request: + branches: + - main +name: unittest +jobs: + unit: + runs-on: ubuntu-latest + strategy: + matrix: + python: ['3.6', '3.7', '3.8', '3.9', '3.10'] + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python }} + - name: Install nox + run: | + python -m pip install --upgrade setuptools pip wheel + python -m pip install nox + - name: Run unit tests + env: + COVERAGE_FILE: .coverage-${{ matrix.python }} + run: | + nox -s unit-${{ matrix.python }} + - name: Upload coverage results + uses: actions/upload-artifact@v2 + with: + name: coverage-artifacts + path: .coverage-${{ matrix.python }} + + cover: + runs-on: ubuntu-latest + needs: + - unit + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: "3.10" + - name: Install coverage + run: | + python -m pip install --upgrade setuptools pip wheel + python -m pip install coverage + - name: Download coverage results + uses: actions/download-artifact@v2 + with: + name: coverage-artifacts + path: .coverage-results/ + - name: Report coverage results + run: | + coverage combine .coverage-results/.coverage* + coverage report --show-missing --fail-under=100 diff --git a/.kokoro/docs/common.cfg b/.kokoro/docs/common.cfg index 8d2b6443..9f4bf34f 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/release.sh b/.kokoro/release.sh index baeeaacd..15219a1e 100755 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -26,7 +26,7 @@ python3 -m pip install --upgrade twine wheel setuptools export PYTHONUNBUFFERED=1 # Move into the package, build the distribution and upload. -TWINE_PASSWORD=$(cat "${KOKORO_GFILE_DIR}/secret_manager/google-cloud-pypi-token") +TWINE_PASSWORD=$(cat "${KOKORO_KEYSTORE_DIR}/73713_google-cloud-pypi-token-keystore-1") cd github/python-iot python3 setup.py sdist bdist_wheel twine upload --username __token__ --password "${TWINE_PASSWORD}" dist/* diff --git a/.kokoro/release/common.cfg b/.kokoro/release/common.cfg index 37d9075e..764da078 100644 --- a/.kokoro/release/common.cfg +++ b/.kokoro/release/common.cfg @@ -23,8 +23,18 @@ env_vars: { value: "github/python-iot/.kokoro/release.sh" } +# Fetch PyPI password +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "google-cloud-pypi-token-keystore-1" + } + } +} + # Tokens needed to report release status back to GitHub env_vars: { key: "SECRET_MANAGER_KEYS" - value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem,google-cloud-pypi-token" + value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem" } diff --git a/.kokoro/samples/lint/common.cfg b/.kokoro/samples/lint/common.cfg index aef9ae58..3f9071b6 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-iot/.kokoro/trampoline.sh" \ No newline at end of file +build_file: "python-iot/.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 00000000..8dae3de5 --- /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-iot/.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-iot/.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 00000000..a1c8d975 --- /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 00000000..1896dcfe --- /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-iot/.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 00000000..71cd1e59 --- /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 00000000..a1c8d975 --- /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 1d2fcd9c..f630deef 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-iot/.kokoro/trampoline.sh" \ No newline at end of file +build_file: "python-iot/.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 50fec964..71cd1e59 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 b9a0e192..12f78320 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-iot/.kokoro/trampoline.sh" \ No newline at end of file +build_file: "python-iot/.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 50fec964..71cd1e59 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 42080967..5e3ddd69 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-iot/.kokoro/trampoline.sh" \ No newline at end of file +build_file: "python-iot/.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 50fec964..71cd1e59 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 276747ee..d4223f92 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-iot/.kokoro/trampoline.sh" \ No newline at end of file +build_file: "python-iot/.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 50fec964..71cd1e59 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 9c281f84..ba3a707b 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-iot - exec .kokoro/test-samples-impl.sh diff --git a/.kokoro/test-samples.sh b/.kokoro/test-samples.sh index 1f9137a8..11c042d3 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-iot - # 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 8b6371ea..6b56f91c 100644 --- a/.repo-metadata.json +++ b/.repo-metadata.json @@ -1,14 +1,17 @@ { - "name": "cloudiot", - "name_pretty": "Google Cloud Internet of Things (IoT) Core", - "product_documentation": "https://cloud.google.com/iot", - "client_documentation": "https://googleapis.dev/python/cloudiot/latest", - "issue_tracker": "https://issuetracker.google.com/issues?q=status:open%20componentid:310170", - "release_level": "ga", - "language": "python", - "library_type": "GAPIC_AUTO", - "repo": "googleapis/python-iot", - "distribution_name": "google-cloud-iot", - "api_id": "cloudiot.googleapis.com", - "requires_billing": true -} \ No newline at end of file + "name": "cloudiot", + "name_pretty": "Google Cloud Internet of Things (IoT) Core", + "product_documentation": "https://cloud.google.com/iot", + "client_documentation": "https://cloud.google.com/python/docs/reference/cloudiot/latest", + "issue_tracker": "https://issuetracker.google.com/issues?q=status:open%20componentid:310170", + "release_level": "stable", + "language": "python", + "library_type": "GAPIC_AUTO", + "repo": "googleapis/python-iot", + "distribution_name": "google-cloud-iot", + "api_id": "cloudiot.googleapis.com", + "requires_billing": true, + "default_version": "v1", + "codeowner_team": "@googleapis/api-iot", + "api_shortname": "cloudiot" +} diff --git a/.trampolinerc b/.trampolinerc index 383b6ec8..0eee72ab 100644 --- a/.trampolinerc +++ b/.trampolinerc @@ -16,15 +16,26 @@ # Add required env vars here. required_envvars+=( - "STAGING_BUCKET" - "V2_STAGING_BUCKET" ) # Add env vars which are passed down into the container here. pass_down_envvars+=( + "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 d3ccf848..cdd0ba13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,34 @@ [1]: https://pypi.org/project/google-cloud-iot/#history +## [2.4.0](https://github.com/googleapis/python-iot/compare/v2.3.0...v2.4.0) (2022-02-24) + + +### Features + +* add api key support ([#244](https://github.com/googleapis/python-iot/issues/244)) ([c3ec086](https://github.com/googleapis/python-iot/commit/c3ec086cbce1171509438ba7ced62b041b690d58)) +* add context manager support in client ([#202](https://github.com/googleapis/python-iot/issues/202)) ([14c4ab6](https://github.com/googleapis/python-iot/commit/14c4ab6bd0589111743b4629fbd10c86a43aa698)) +* add support for Python 3.9 / 3.10 ([#220](https://github.com/googleapis/python-iot/issues/220)) ([6038e0c](https://github.com/googleapis/python-iot/commit/6038e0cf8abbdcf0775e02844f86d1909b2857e0)), closes [#221](https://github.com/googleapis/python-iot/issues/221) + + +### Bug Fixes + +* **deps:** drop packaging dependency ([b6df5e4](https://github.com/googleapis/python-iot/commit/b6df5e4ba104003123ebac6687e55fdef176daf0)) +* **deps:** require google-api-core>=1.28.0 ([b6df5e4](https://github.com/googleapis/python-iot/commit/b6df5e4ba104003123ebac6687e55fdef176daf0)) +* **deps:** require proto-plus>=1.15.0 ([b6df5e4](https://github.com/googleapis/python-iot/commit/b6df5e4ba104003123ebac6687e55fdef176daf0)) +* fix extras_require typo in setup.py ([#210](https://github.com/googleapis/python-iot/issues/210)) ([c1149b0](https://github.com/googleapis/python-iot/commit/c1149b010f358debbebb5eea483cc628ec91549d)) +* improper types in pagers generation ([18d869a](https://github.com/googleapis/python-iot/commit/18d869a87e3346c8dabb3bd27a3ee74c237ce370)) +* provide appropriate mock values for message body fields ([b6df5e4](https://github.com/googleapis/python-iot/commit/b6df5e4ba104003123ebac6687e55fdef176daf0)) +* resolve DuplicateCredentialArgs error when using credentials_file ([e9e71b1](https://github.com/googleapis/python-iot/commit/e9e71b19712915f7a65a212c75344609183a2298)) + + +### Documentation + +* add generated snippets ([#253](https://github.com/googleapis/python-iot/issues/253)) ([a68cbf4](https://github.com/googleapis/python-iot/commit/a68cbf47f79e5d16f921920825014c01eba0b448)) +* list oneofs in docstring ([b6df5e4](https://github.com/googleapis/python-iot/commit/b6df5e4ba104003123ebac6687e55fdef176daf0)) +* **samples:** modify accesstoken sample to use environment identity during setup ([#245](https://github.com/googleapis/python-iot/issues/245)) ([63f5a93](https://github.com/googleapis/python-iot/commit/63f5a9327c36714b688fd742fe8beeb0182e2146)) +* **samples:** resolve TypeError in create_iot_topic ([31a5fa8](https://github.com/googleapis/python-iot/commit/31a5fa89c34a7f6fea5cdcd17381ffce831584b3)) + ## [2.3.0](https://www.github.com/googleapis/python-iot/compare/v2.2.1...v2.3.0) (2021-09-24) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 2ae49064..898eb9d4 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 @@ -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:: @@ -225,11 +225,13 @@ 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`_. diff --git a/README.rst b/README.rst index bd4f48fa..44f56ec6 100644 --- a/README.rst +++ b/README.rst @@ -16,7 +16,7 @@ connect to the Google Cloud Platform. .. |versions| image:: https://img.shields.io/pypi/pyversions/google-cloud-iot.svg :target: https://pypi.org/project/google-cloud-iot/ .. _Cloud IoT API: https://cloud.google.com/iot -.. _Client Library Documentation: https://googleapis.dev/python/cloudiot/latest +.. _Client Library Documentation: https://cloud.google.com/python/docs/reference/cloudiot/latest .. _Product Documentation: https://cloud.google.com/iot Quick Start diff --git a/google/cloud/iot_v1/services/device_manager/async_client.py b/google/cloud/iot_v1/services/device_manager/async_client.py index 08a35bd7..2f2ac4d8 100644 --- a/google/cloud/iot_v1/services/device_manager/async_client.py +++ b/google/cloud/iot_v1/services/device_manager/async_client.py @@ -16,16 +16,21 @@ from collections import OrderedDict import functools import re -from typing import Dict, Sequence, Tuple, Type, Union +from typing import Dict, Optional, Sequence, Tuple, Type, Union import pkg_resources -import google.api_core.client_options as ClientOptions # type: ignore -from google.api_core import exceptions 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.api_core.client_options import ClientOptions +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + from google.cloud.iot_v1.services.device_manager import pagers from google.cloud.iot_v1.types import device_manager from google.cloud.iot_v1.types import resources @@ -111,6 +116,42 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): from_service_account_json = from_service_account_file + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return DeviceManagerClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + @property def transport(self) -> DeviceManagerTransport: """Returns the transport used by the client instance. @@ -173,18 +214,37 @@ def __init__( async def create_device_registry( self, - request: device_manager.CreateDeviceRegistryRequest = None, + request: Union[device_manager.CreateDeviceRegistryRequest, dict] = None, *, parent: str = None, device_registry: resources.DeviceRegistry = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> resources.DeviceRegistry: r"""Creates a device registry that contains devices. + .. code-block:: + + from google.cloud import iot_v1 + + def sample_create_device_registry(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.CreateDeviceRegistryRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_device_registry(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.CreateDeviceRegistryRequest`): + request (Union[google.cloud.iot_v1.types.CreateDeviceRegistryRequest, dict]): The request object. Request for `CreateDeviceRegistry`. parent (:class:`str`): Required. The project and cloud region where this device @@ -214,7 +274,7 @@ async def create_device_registry( A container for a group of devices. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([parent, device_registry]) if request is not None and has_flattened_params: @@ -254,17 +314,36 @@ async def create_device_registry( async def get_device_registry( self, - request: device_manager.GetDeviceRegistryRequest = None, + request: Union[device_manager.GetDeviceRegistryRequest, 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]] = (), ) -> resources.DeviceRegistry: r"""Gets a device registry configuration. + .. code-block:: + + from google.cloud import iot_v1 + + def sample_get_device_registry(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.GetDeviceRegistryRequest( + name="name_value", + ) + + # Make the request + response = client.get_device_registry(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.GetDeviceRegistryRequest`): + request (Union[google.cloud.iot_v1.types.GetDeviceRegistryRequest, dict]): The request object. Request for `GetDeviceRegistry`. name (:class:`str`): Required. The name of the device registry. For example, @@ -284,7 +363,7 @@ async def get_device_registry( A container for a group of devices. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name]) if request is not None and has_flattened_params: @@ -332,18 +411,36 @@ async def get_device_registry( async def update_device_registry( self, - request: device_manager.UpdateDeviceRegistryRequest = None, + request: Union[device_manager.UpdateDeviceRegistryRequest, dict] = None, *, device_registry: resources.DeviceRegistry = 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]] = (), ) -> resources.DeviceRegistry: r"""Updates a device registry configuration. + .. code-block:: + + from google.cloud import iot_v1 + + def sample_update_device_registry(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.UpdateDeviceRegistryRequest( + ) + + # Make the request + response = client.update_device_registry(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.UpdateDeviceRegistryRequest`): + request (Union[google.cloud.iot_v1.types.UpdateDeviceRegistryRequest, dict]): The request object. Request for `UpdateDeviceRegistry`. device_registry (:class:`google.cloud.iot_v1.types.DeviceRegistry`): Required. The new values for the device registry. The @@ -376,7 +473,7 @@ async def update_device_registry( A container for a group of devices. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([device_registry, update_mask]) if request is not None and has_flattened_params: @@ -418,17 +515,33 @@ async def update_device_registry( async def delete_device_registry( self, - request: device_manager.DeleteDeviceRegistryRequest = None, + request: Union[device_manager.DeleteDeviceRegistryRequest, 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 a device registry configuration. + .. code-block:: + + from google.cloud import iot_v1 + + def sample_delete_device_registry(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.DeleteDeviceRegistryRequest( + name="name_value", + ) + + # Make the request + client.delete_device_registry(request=request) + Args: - request (:class:`google.cloud.iot_v1.types.DeleteDeviceRegistryRequest`): + request (Union[google.cloud.iot_v1.types.DeleteDeviceRegistryRequest, dict]): The request object. Request for `DeleteDeviceRegistry`. name (:class:`str`): Required. The name of the device registry. For example, @@ -444,7 +557,7 @@ async def delete_device_registry( sent along with the request as metadata. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name]) if request is not None and has_flattened_params: @@ -491,17 +604,37 @@ async def delete_device_registry( async def list_device_registries( self, - request: device_manager.ListDeviceRegistriesRequest = None, + request: Union[device_manager.ListDeviceRegistriesRequest, 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.ListDeviceRegistriesAsyncPager: r"""Lists device registries. + .. code-block:: + + from google.cloud import iot_v1 + + def sample_list_device_registries(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ListDeviceRegistriesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_device_registries(request=request) + + # Handle the response + for response in page_result: + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.ListDeviceRegistriesRequest`): + request (Union[google.cloud.iot_v1.types.ListDeviceRegistriesRequest, dict]): The request object. Request for `ListDeviceRegistries`. parent (:class:`str`): Required. The project and cloud region path. For @@ -526,7 +659,7 @@ async def list_device_registries( """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([parent]) if request is not None and has_flattened_params: @@ -580,18 +713,37 @@ async def list_device_registries( async def create_device( self, - request: device_manager.CreateDeviceRequest = None, + request: Union[device_manager.CreateDeviceRequest, dict] = None, *, parent: str = None, device: resources.Device = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> resources.Device: r"""Creates a device in a device registry. + .. code-block:: + + from google.cloud import iot_v1 + + def sample_create_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.CreateDeviceRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_device(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.CreateDeviceRequest`): + request (Union[google.cloud.iot_v1.types.CreateDeviceRequest, dict]): The request object. Request for `CreateDevice`. parent (:class:`str`): Required. The name of the device registry where this @@ -621,7 +773,7 @@ async def create_device( The device resource. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([parent, device]) if request is not None and has_flattened_params: @@ -661,17 +813,36 @@ async def create_device( async def get_device( self, - request: device_manager.GetDeviceRequest = None, + request: Union[device_manager.GetDeviceRequest, 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]] = (), ) -> resources.Device: r"""Gets details about a device. + .. code-block:: + + from google.cloud import iot_v1 + + def sample_get_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.GetDeviceRequest( + name="name_value", + ) + + # Make the request + response = client.get_device(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.GetDeviceRequest`): + request (Union[google.cloud.iot_v1.types.GetDeviceRequest, dict]): The request object. Request for `GetDevice`. name (:class:`str`): Required. The name of the device. For example, @@ -693,7 +864,7 @@ async def get_device( The device resource. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name]) if request is not None and has_flattened_params: @@ -741,18 +912,36 @@ async def get_device( async def update_device( self, - request: device_manager.UpdateDeviceRequest = None, + request: Union[device_manager.UpdateDeviceRequest, dict] = None, *, device: resources.Device = 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]] = (), ) -> resources.Device: r"""Updates a device. + .. code-block:: + + from google.cloud import iot_v1 + + def sample_update_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.UpdateDeviceRequest( + ) + + # Make the request + response = client.update_device(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.UpdateDeviceRequest`): + request (Union[google.cloud.iot_v1.types.UpdateDeviceRequest, dict]): The request object. Request for `UpdateDevice`. device (:class:`google.cloud.iot_v1.types.Device`): Required. The new values for the device. The ``id`` and @@ -785,7 +974,7 @@ async def update_device( The device resource. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([device, update_mask]) if request is not None and has_flattened_params: @@ -827,17 +1016,33 @@ async def update_device( async def delete_device( self, - request: device_manager.DeleteDeviceRequest = None, + request: Union[device_manager.DeleteDeviceRequest, 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 a device. + .. code-block:: + + from google.cloud import iot_v1 + + def sample_delete_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.DeleteDeviceRequest( + name="name_value", + ) + + # Make the request + client.delete_device(request=request) + Args: - request (:class:`google.cloud.iot_v1.types.DeleteDeviceRequest`): + request (Union[google.cloud.iot_v1.types.DeleteDeviceRequest, dict]): The request object. Request for `DeleteDevice`. name (:class:`str`): Required. The name of the device. For example, @@ -855,7 +1060,7 @@ async def delete_device( sent along with the request as metadata. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name]) if request is not None and has_flattened_params: @@ -902,17 +1107,37 @@ async def delete_device( async def list_devices( self, - request: device_manager.ListDevicesRequest = None, + request: Union[device_manager.ListDevicesRequest, 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.ListDevicesAsyncPager: r"""List devices in a device registry. + .. code-block:: + + from google.cloud import iot_v1 + + def sample_list_devices(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ListDevicesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_devices(request=request) + + # Handle the response + for response in page_result: + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.ListDevicesRequest`): + request (Union[google.cloud.iot_v1.types.ListDevicesRequest, dict]): The request object. Request for `ListDevices`. parent (:class:`str`): Required. The device registry path. Required. For @@ -937,7 +1162,7 @@ async def list_devices( """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([parent]) if request is not None and has_flattened_params: @@ -991,11 +1216,11 @@ async def list_devices( async def modify_cloud_to_device_config( self, - request: device_manager.ModifyCloudToDeviceConfigRequest = None, + request: Union[device_manager.ModifyCloudToDeviceConfigRequest, dict] = None, *, name: str = None, binary_data: bytes = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> resources.DeviceConfig: @@ -1003,8 +1228,29 @@ async def modify_cloud_to_device_config( eventually sent from the Cloud IoT Core servers. Returns the modified configuration version and its metadata. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_modify_cloud_to_device_config(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ModifyCloudToDeviceConfigRequest( + name="name_value", + binary_data=b'binary_data_blob', + ) + + # Make the request + response = client.modify_cloud_to_device_config(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.ModifyCloudToDeviceConfigRequest`): + request (Union[google.cloud.iot_v1.types.ModifyCloudToDeviceConfigRequest, dict]): The request object. Request for `ModifyCloudToDeviceConfig`. name (:class:`str`): @@ -1036,7 +1282,7 @@ async def modify_cloud_to_device_config( """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name, binary_data]) if request is not None and has_flattened_params: @@ -1087,18 +1333,38 @@ async def modify_cloud_to_device_config( async def list_device_config_versions( self, - request: device_manager.ListDeviceConfigVersionsRequest = None, + request: Union[device_manager.ListDeviceConfigVersionsRequest, 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]] = (), ) -> device_manager.ListDeviceConfigVersionsResponse: r"""Lists the last few versions of the device configuration in descending order (i.e.: newest first). + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_list_device_config_versions(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ListDeviceConfigVersionsRequest( + name="name_value", + ) + + # Make the request + response = client.list_device_config_versions(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.ListDeviceConfigVersionsRequest`): + request (Union[google.cloud.iot_v1.types.ListDeviceConfigVersionsRequest, dict]): The request object. Request for `ListDeviceConfigVersions`. name (:class:`str`): @@ -1121,7 +1387,7 @@ async def list_device_config_versions( Response for ListDeviceConfigVersions. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name]) if request is not None and has_flattened_params: @@ -1169,18 +1435,38 @@ async def list_device_config_versions( async def list_device_states( self, - request: device_manager.ListDeviceStatesRequest = None, + request: Union[device_manager.ListDeviceStatesRequest, 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]] = (), ) -> device_manager.ListDeviceStatesResponse: r"""Lists the last few versions of the device state in descending order (i.e.: newest first). + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_list_device_states(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ListDeviceStatesRequest( + name="name_value", + ) + + # Make the request + response = client.list_device_states(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.ListDeviceStatesRequest`): + request (Union[google.cloud.iot_v1.types.ListDeviceStatesRequest, dict]): The request object. Request for `ListDeviceStates`. name (:class:`str`): Required. The name of the device. For example, @@ -1202,7 +1488,7 @@ async def list_device_states( Response for ListDeviceStates. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name]) if request is not None and has_flattened_params: @@ -1250,18 +1536,38 @@ async def list_device_states( async def set_iam_policy( self, - request: iam_policy_pb2.SetIamPolicyRequest = None, + request: Union[iam_policy_pb2.SetIamPolicyRequest, dict] = None, *, resource: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> policy_pb2.Policy: r"""Sets the access control policy on the specified resource. Replaces any existing policy. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_set_iam_policy(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.SetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = client.set_iam_policy(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.iam.v1.iam_policy_pb2.SetIamPolicyRequest`): + request (Union[google.iam.v1.iam_policy_pb2.SetIamPolicyRequest, dict]): The request object. Request message for `SetIamPolicy` method. resource (:class:`str`): @@ -1339,7 +1645,7 @@ async def set_iam_policy( """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([resource]) if request is not None and has_flattened_params: @@ -1377,10 +1683,10 @@ async def set_iam_policy( async def get_iam_policy( self, - request: iam_policy_pb2.GetIamPolicyRequest = None, + request: Union[iam_policy_pb2.GetIamPolicyRequest, dict] = None, *, resource: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> policy_pb2.Policy: @@ -1388,8 +1694,28 @@ async def get_iam_policy( Returns an empty policy if the resource exists and does not have a policy set. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_get_iam_policy(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.GetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = client.get_iam_policy(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.iam.v1.iam_policy_pb2.GetIamPolicyRequest`): + request (Union[google.iam.v1.iam_policy_pb2.GetIamPolicyRequest, dict]): The request object. Request message for `GetIamPolicy` method. resource (:class:`str`): @@ -1467,7 +1793,7 @@ async def get_iam_policy( """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([resource]) if request is not None and has_flattened_params: @@ -1505,11 +1831,11 @@ async def get_iam_policy( async def test_iam_permissions( self, - request: iam_policy_pb2.TestIamPermissionsRequest = None, + request: Union[iam_policy_pb2.TestIamPermissionsRequest, dict] = None, *, resource: str = None, permissions: Sequence[str] = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> iam_policy_pb2.TestIamPermissionsResponse: @@ -1517,8 +1843,29 @@ async def test_iam_permissions( If the resource does not exist, this will return an empty set of permissions, not a NOT_FOUND error. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_test_iam_permissions(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.TestIamPermissionsRequest( + resource="resource_value", + permissions=['permissions_value_1', 'permissions_value_2'], + ) + + # Make the request + response = client.test_iam_permissions(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest`): + request (Union[google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest, dict]): The request object. Request message for `TestIamPermissions` method. resource (:class:`str`): @@ -1550,7 +1897,7 @@ async def test_iam_permissions( Response message for TestIamPermissions method. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([resource, permissions]) if request is not None and has_flattened_params: @@ -1590,12 +1937,12 @@ async def test_iam_permissions( async def send_command_to_device( self, - request: device_manager.SendCommandToDeviceRequest = None, + request: Union[device_manager.SendCommandToDeviceRequest, dict] = None, *, name: str = None, binary_data: bytes = None, subfolder: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> device_manager.SendCommandToDeviceResponse: @@ -1617,8 +1964,29 @@ async def send_command_to_device( guaranteed; for QoS 0, no acknowledgment will be expected from the device. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_send_command_to_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.SendCommandToDeviceRequest( + name="name_value", + binary_data=b'binary_data_blob', + ) + + # Make the request + response = client.send_command_to_device(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.SendCommandToDeviceRequest`): + request (Union[google.cloud.iot_v1.types.SendCommandToDeviceRequest, dict]): The request object. Request for `SendCommandToDevice`. name (:class:`str`): Required. The name of the device. For example, @@ -1641,12 +2009,13 @@ async def send_command_to_device( If empty, the command will be delivered to the /devices/{device-id}/commands topic, otherwise it will be delivered to - the /devices/{device- - id}/commands/{subfolder} topic. Multi- - level subfolders are allowed. This field - must not have more than 256 characters, - and must not contain any MQTT wildcards - ("+" or "#") or null characters. + the + /devices/{device-id}/commands/{subfolder} + topic. Multi-level subfolders are + allowed. This field must not have more + than 256 characters, and must not + contain any MQTT wildcards ("+" or "#") + or null characters. This corresponds to the ``subfolder`` field on the ``request`` instance; if ``request`` is provided, this @@ -1662,7 +2031,7 @@ async def send_command_to_device( Response for SendCommandToDevice. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name, binary_data, subfolder]) if request is not None and has_flattened_params: @@ -1715,19 +2084,40 @@ async def send_command_to_device( async def bind_device_to_gateway( self, - request: device_manager.BindDeviceToGatewayRequest = None, + request: Union[device_manager.BindDeviceToGatewayRequest, dict] = None, *, parent: str = None, gateway_id: str = None, device_id: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> device_manager.BindDeviceToGatewayResponse: r"""Associates the device with the gateway. + .. code-block:: + + from google.cloud import iot_v1 + + def sample_bind_device_to_gateway(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.BindDeviceToGatewayRequest( + parent="parent_value", + gateway_id="gateway_id_value", + device_id="device_id_value", + ) + + # Make the request + response = client.bind_device_to_gateway(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.BindDeviceToGatewayRequest`): + request (Union[google.cloud.iot_v1.types.BindDeviceToGatewayRequest, dict]): The request object. Request for `BindDeviceToGateway`. parent (:class:`str`): Required. The name of the registry. For example, @@ -1762,7 +2152,7 @@ async def bind_device_to_gateway( Response for BindDeviceToGateway. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([parent, gateway_id, device_id]) if request is not None and has_flattened_params: @@ -1804,20 +2194,42 @@ async def bind_device_to_gateway( async def unbind_device_from_gateway( self, - request: device_manager.UnbindDeviceFromGatewayRequest = None, + request: Union[device_manager.UnbindDeviceFromGatewayRequest, dict] = None, *, parent: str = None, gateway_id: str = None, device_id: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> device_manager.UnbindDeviceFromGatewayResponse: r"""Deletes the association between the device and the gateway. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_unbind_device_from_gateway(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.UnbindDeviceFromGatewayRequest( + parent="parent_value", + gateway_id="gateway_id_value", + device_id="device_id_value", + ) + + # Make the request + response = client.unbind_device_from_gateway(request=request) + + # Handle the response + print(response) + Args: - request (:class:`google.cloud.iot_v1.types.UnbindDeviceFromGatewayRequest`): + request (Union[google.cloud.iot_v1.types.UnbindDeviceFromGatewayRequest, dict]): The request object. Request for `UnbindDeviceFromGateway`. parent (:class:`str`): @@ -1853,7 +2265,7 @@ async def unbind_device_from_gateway( Response for UnbindDeviceFromGateway. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([parent, gateway_id, device_id]) if request is not None and has_flattened_params: @@ -1893,6 +2305,12 @@ async def unbind_device_from_gateway( # 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/iot_v1/services/device_manager/client.py b/google/cloud/iot_v1/services/device_manager/client.py index 7b32007b..4f26c108 100644 --- a/google/cloud/iot_v1/services/device_manager/client.py +++ b/google/cloud/iot_v1/services/device_manager/client.py @@ -14,22 +14,26 @@ # limitations under the License. # from collections import OrderedDict -from distutils import util import os import re 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 -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.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object] # type: ignore + from google.cloud.iot_v1.services.device_manager import pagers from google.cloud.iot_v1.types import device_manager from google.cloud.iot_v1.types import resources @@ -252,6 +256,73 @@ def parse_common_location_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) return m.groupdict() if m else {} + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variabel is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_client_cert not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert == "true": + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + def __init__( self, *, @@ -302,50 +373,22 @@ def __init__( if client_options is None: client_options = client_options_lib.ClientOptions() - # Create SSL credentials for mutual TLS if needed. - use_client_cert = bool( - util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) + api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source( + client_options ) - client_cert_source_func = None - is_mtls = False - if use_client_cert: - if client_options.client_cert_source: - is_mtls = True - client_cert_source_func = client_options.client_cert_source - else: - is_mtls = mtls.has_default_client_cert_source() - if is_mtls: - client_cert_source_func = mtls.default_client_cert_source() - else: - client_cert_source_func = None - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - else: - use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_mtls_env == "never": - api_endpoint = self.DEFAULT_ENDPOINT - elif use_mtls_env == "always": - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - elif use_mtls_env == "auto": - if is_mtls: - api_endpoint = self.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = self.DEFAULT_ENDPOINT - else: - raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " - "values: never, auto, always" - ) + api_key_value = getattr(client_options, "api_key", None) + if api_key_value and credentials: + raise ValueError( + "client_options.api_key and credentials are mutually exclusive" + ) # Save or instantiate the transport. # Ordinarily, we provide the transport, but allowing a custom transport # instance provides an extensibility point for unusual situations. if isinstance(transport, DeviceManagerTransport): # transport is a DeviceManagerTransport instance. - if credentials or client_options.credentials_file: + if credentials or client_options.credentials_file or api_key_value: raise ValueError( "When providing a transport instance, " "provide its credentials directly." @@ -357,6 +400,15 @@ def __init__( ) self._transport = transport else: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + Transport = type(self).get_transport_class(transport) self._transport = Transport( credentials=credentials, @@ -366,10 +418,7 @@ 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 create_device_registry( @@ -378,12 +427,32 @@ def create_device_registry( *, parent: str = None, device_registry: resources.DeviceRegistry = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> resources.DeviceRegistry: r"""Creates a device registry that contains devices. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_create_device_registry(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.CreateDeviceRegistryRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_device_registry(request=request) + + # Handle the response + print(response) + Args: request (Union[google.cloud.iot_v1.types.CreateDeviceRegistryRequest, dict]): The request object. Request for `CreateDeviceRegistry`. @@ -415,7 +484,7 @@ def create_device_registry( A container for a group of devices. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([parent, device_registry]) if request is not None and has_flattened_params: @@ -458,12 +527,32 @@ def get_device_registry( request: Union[device_manager.GetDeviceRegistryRequest, 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]] = (), ) -> resources.DeviceRegistry: r"""Gets a device registry configuration. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_get_device_registry(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.GetDeviceRegistryRequest( + name="name_value", + ) + + # Make the request + response = client.get_device_registry(request=request) + + # Handle the response + print(response) + Args: request (Union[google.cloud.iot_v1.types.GetDeviceRegistryRequest, dict]): The request object. Request for `GetDeviceRegistry`. @@ -485,7 +574,7 @@ def get_device_registry( A container for a group of devices. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name]) if request is not None and has_flattened_params: @@ -527,12 +616,31 @@ def update_device_registry( *, device_registry: resources.DeviceRegistry = 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]] = (), ) -> resources.DeviceRegistry: r"""Updates a device registry configuration. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_update_device_registry(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.UpdateDeviceRegistryRequest( + ) + + # Make the request + response = client.update_device_registry(request=request) + + # Handle the response + print(response) + Args: request (Union[google.cloud.iot_v1.types.UpdateDeviceRegistryRequest, dict]): The request object. Request for `UpdateDeviceRegistry`. @@ -567,7 +675,7 @@ def update_device_registry( A container for a group of devices. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([device_registry, update_mask]) if request is not None and has_flattened_params: @@ -612,12 +720,29 @@ def delete_device_registry( request: Union[device_manager.DeleteDeviceRegistryRequest, 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 a device registry configuration. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_delete_device_registry(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.DeleteDeviceRegistryRequest( + name="name_value", + ) + + # Make the request + client.delete_device_registry(request=request) + Args: request (Union[google.cloud.iot_v1.types.DeleteDeviceRegistryRequest, dict]): The request object. Request for `DeleteDeviceRegistry`. @@ -635,7 +760,7 @@ def delete_device_registry( sent along with the request as metadata. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name]) if request is not None and has_flattened_params: @@ -675,12 +800,33 @@ def list_device_registries( request: Union[device_manager.ListDeviceRegistriesRequest, 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.ListDeviceRegistriesPager: r"""Lists device registries. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_list_device_registries(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ListDeviceRegistriesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_device_registries(request=request) + + # Handle the response + for response in page_result: + print(response) + Args: request (Union[google.cloud.iot_v1.types.ListDeviceRegistriesRequest, dict]): The request object. Request for `ListDeviceRegistries`. @@ -707,7 +853,7 @@ def list_device_registries( """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([parent]) if request is not None and has_flattened_params: @@ -755,12 +901,32 @@ def create_device( *, parent: str = None, device: resources.Device = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> resources.Device: r"""Creates a device in a device registry. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_create_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.CreateDeviceRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_device(request=request) + + # Handle the response + print(response) + Args: request (Union[google.cloud.iot_v1.types.CreateDeviceRequest, dict]): The request object. Request for `CreateDevice`. @@ -792,7 +958,7 @@ def create_device( The device resource. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([parent, device]) if request is not None and has_flattened_params: @@ -835,12 +1001,32 @@ def get_device( request: Union[device_manager.GetDeviceRequest, 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]] = (), ) -> resources.Device: r"""Gets details about a device. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_get_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.GetDeviceRequest( + name="name_value", + ) + + # Make the request + response = client.get_device(request=request) + + # Handle the response + print(response) + Args: request (Union[google.cloud.iot_v1.types.GetDeviceRequest, dict]): The request object. Request for `GetDevice`. @@ -864,7 +1050,7 @@ def get_device( The device resource. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name]) if request is not None and has_flattened_params: @@ -906,12 +1092,31 @@ def update_device( *, device: resources.Device = 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]] = (), ) -> resources.Device: r"""Updates a device. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_update_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.UpdateDeviceRequest( + ) + + # Make the request + response = client.update_device(request=request) + + # Handle the response + print(response) + Args: request (Union[google.cloud.iot_v1.types.UpdateDeviceRequest, dict]): The request object. Request for `UpdateDevice`. @@ -946,7 +1151,7 @@ def update_device( The device resource. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([device, update_mask]) if request is not None and has_flattened_params: @@ -991,12 +1196,29 @@ def delete_device( request: Union[device_manager.DeleteDeviceRequest, 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 a device. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_delete_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.DeleteDeviceRequest( + name="name_value", + ) + + # Make the request + client.delete_device(request=request) + Args: request (Union[google.cloud.iot_v1.types.DeleteDeviceRequest, dict]): The request object. Request for `DeleteDevice`. @@ -1016,7 +1238,7 @@ def delete_device( sent along with the request as metadata. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name]) if request is not None and has_flattened_params: @@ -1056,12 +1278,33 @@ def list_devices( request: Union[device_manager.ListDevicesRequest, 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.ListDevicesPager: r"""List devices in a device registry. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_list_devices(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ListDevicesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_devices(request=request) + + # Handle the response + for response in page_result: + print(response) + Args: request (Union[google.cloud.iot_v1.types.ListDevicesRequest, dict]): The request object. Request for `ListDevices`. @@ -1088,7 +1331,7 @@ def list_devices( """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([parent]) if request is not None and has_flattened_params: @@ -1136,7 +1379,7 @@ def modify_cloud_to_device_config( *, name: str = None, binary_data: bytes = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> resources.DeviceConfig: @@ -1144,6 +1387,28 @@ def modify_cloud_to_device_config( eventually sent from the Cloud IoT Core servers. Returns the modified configuration version and its metadata. + + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_modify_cloud_to_device_config(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ModifyCloudToDeviceConfigRequest( + name="name_value", + binary_data=b'binary_data_blob', + ) + + # Make the request + response = client.modify_cloud_to_device_config(request=request) + + # Handle the response + print(response) + Args: request (Union[google.cloud.iot_v1.types.ModifyCloudToDeviceConfigRequest, dict]): The request object. Request for @@ -1177,7 +1442,7 @@ def modify_cloud_to_device_config( """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name, binary_data]) if request is not None and has_flattened_params: @@ -1222,13 +1487,34 @@ def list_device_config_versions( request: Union[device_manager.ListDeviceConfigVersionsRequest, 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]] = (), ) -> device_manager.ListDeviceConfigVersionsResponse: r"""Lists the last few versions of the device configuration in descending order (i.e.: newest first). + + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_list_device_config_versions(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ListDeviceConfigVersionsRequest( + name="name_value", + ) + + # Make the request + response = client.list_device_config_versions(request=request) + + # Handle the response + print(response) + Args: request (Union[google.cloud.iot_v1.types.ListDeviceConfigVersionsRequest, dict]): The request object. Request for @@ -1253,7 +1539,7 @@ def list_device_config_versions( Response for ListDeviceConfigVersions. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name]) if request is not None and has_flattened_params: @@ -1296,13 +1582,34 @@ def list_device_states( request: Union[device_manager.ListDeviceStatesRequest, 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]] = (), ) -> device_manager.ListDeviceStatesResponse: r"""Lists the last few versions of the device state in descending order (i.e.: newest first). + + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_list_device_states(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ListDeviceStatesRequest( + name="name_value", + ) + + # Make the request + response = client.list_device_states(request=request) + + # Handle the response + print(response) + Args: request (Union[google.cloud.iot_v1.types.ListDeviceStatesRequest, dict]): The request object. Request for `ListDeviceStates`. @@ -1326,7 +1633,7 @@ def list_device_states( Response for ListDeviceStates. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name]) if request is not None and has_flattened_params: @@ -1367,13 +1674,34 @@ def set_iam_policy( request: Union[iam_policy_pb2.SetIamPolicyRequest, dict] = None, *, resource: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> policy_pb2.Policy: r"""Sets the access control policy on the specified resource. Replaces any existing policy. + + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_set_iam_policy(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.SetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = client.set_iam_policy(request=request) + + # Handle the response + print(response) + Args: request (Union[google.iam.v1.iam_policy_pb2.SetIamPolicyRequest, dict]): The request object. Request message for `SetIamPolicy` @@ -1453,7 +1781,7 @@ def set_iam_policy( """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([resource]) if request is not None and has_flattened_params: @@ -1493,7 +1821,7 @@ def get_iam_policy( request: Union[iam_policy_pb2.GetIamPolicyRequest, dict] = None, *, resource: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> policy_pb2.Policy: @@ -1501,6 +1829,27 @@ def get_iam_policy( Returns an empty policy if the resource exists and does not have a policy set. + + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_get_iam_policy(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.GetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = client.get_iam_policy(request=request) + + # Handle the response + print(response) + Args: request (Union[google.iam.v1.iam_policy_pb2.GetIamPolicyRequest, dict]): The request object. Request message for `GetIamPolicy` @@ -1580,7 +1929,7 @@ def get_iam_policy( """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([resource]) if request is not None and has_flattened_params: @@ -1621,7 +1970,7 @@ def test_iam_permissions( *, resource: str = None, permissions: Sequence[str] = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> iam_policy_pb2.TestIamPermissionsResponse: @@ -1629,6 +1978,28 @@ def test_iam_permissions( If the resource does not exist, this will return an empty set of permissions, not a NOT_FOUND error. + + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_test_iam_permissions(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.TestIamPermissionsRequest( + resource="resource_value", + permissions=['permissions_value_1', 'permissions_value_2'], + ) + + # Make the request + response = client.test_iam_permissions(request=request) + + # Handle the response + print(response) + Args: request (Union[google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest, dict]): The request object. Request message for @@ -1662,7 +2033,7 @@ def test_iam_permissions( Response message for TestIamPermissions method. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([resource, permissions]) if request is not None and has_flattened_params: @@ -1706,7 +2077,7 @@ def send_command_to_device( name: str = None, binary_data: bytes = None, subfolder: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> device_manager.SendCommandToDeviceResponse: @@ -1728,6 +2099,28 @@ def send_command_to_device( guaranteed; for QoS 0, no acknowledgment will be expected from the device. + + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_send_command_to_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.SendCommandToDeviceRequest( + name="name_value", + binary_data=b'binary_data_blob', + ) + + # Make the request + response = client.send_command_to_device(request=request) + + # Handle the response + print(response) + Args: request (Union[google.cloud.iot_v1.types.SendCommandToDeviceRequest, dict]): The request object. Request for `SendCommandToDevice`. @@ -1752,12 +2145,13 @@ def send_command_to_device( If empty, the command will be delivered to the /devices/{device-id}/commands topic, otherwise it will be delivered to - the /devices/{device- - id}/commands/{subfolder} topic. Multi- - level subfolders are allowed. This field - must not have more than 256 characters, - and must not contain any MQTT wildcards - ("+" or "#") or null characters. + the + /devices/{device-id}/commands/{subfolder} + topic. Multi-level subfolders are + allowed. This field must not have more + than 256 characters, and must not + contain any MQTT wildcards ("+" or "#") + or null characters. This corresponds to the ``subfolder`` field on the ``request`` instance; if ``request`` is provided, this @@ -1773,7 +2167,7 @@ def send_command_to_device( Response for SendCommandToDevice. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([name, binary_data, subfolder]) if request is not None and has_flattened_params: @@ -1820,12 +2214,34 @@ def bind_device_to_gateway( parent: str = None, gateway_id: str = None, device_id: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> device_manager.BindDeviceToGatewayResponse: r"""Associates the device with the gateway. + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_bind_device_to_gateway(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.BindDeviceToGatewayRequest( + parent="parent_value", + gateway_id="gateway_id_value", + device_id="device_id_value", + ) + + # Make the request + response = client.bind_device_to_gateway(request=request) + + # Handle the response + print(response) + Args: request (Union[google.cloud.iot_v1.types.BindDeviceToGatewayRequest, dict]): The request object. Request for `BindDeviceToGateway`. @@ -1862,7 +2278,7 @@ def bind_device_to_gateway( Response for BindDeviceToGateway. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([parent, gateway_id, device_id]) if request is not None and has_flattened_params: @@ -1909,13 +2325,36 @@ def unbind_device_from_gateway( parent: str = None, gateway_id: str = None, device_id: str = None, - retry: retries.Retry = gapic_v1.method.DEFAULT, + retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: float = None, metadata: Sequence[Tuple[str, str]] = (), ) -> device_manager.UnbindDeviceFromGatewayResponse: r"""Deletes the association between the device and the gateway. + + + .. code-block:: + + from google.cloud import iot_v1 + + def sample_unbind_device_from_gateway(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.UnbindDeviceFromGatewayRequest( + parent="parent_value", + gateway_id="gateway_id_value", + device_id="device_id_value", + ) + + # Make the request + response = client.unbind_device_from_gateway(request=request) + + # Handle the response + print(response) + Args: request (Union[google.cloud.iot_v1.types.UnbindDeviceFromGatewayRequest, dict]): The request object. Request for @@ -1953,7 +2392,7 @@ def unbind_device_from_gateway( Response for UnbindDeviceFromGateway. """ # Create or coerce a protobuf request object. - # Sanity check: If we got a request object, we should *not* have + # Quick check: If we got a request object, we should *not* have # gotten any keyword arguments that map to the request. has_flattened_params = any([parent, gateway_id, device_id]) if request is not None and has_flattened_params: @@ -1995,6 +2434,19 @@ def unbind_device_from_gateway( # 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/iot_v1/services/device_manager/pagers.py b/google/cloud/iot_v1/services/device_manager/pagers.py index 166e0f5b..e84f8b43 100644 --- a/google/cloud/iot_v1/services/device_manager/pagers.py +++ b/google/cloud/iot_v1/services/device_manager/pagers.py @@ -15,13 +15,13 @@ # from typing import ( Any, - AsyncIterable, + AsyncIterator, Awaitable, Callable, - Iterable, Sequence, Tuple, Optional, + Iterator, ) from google.cloud.iot_v1.types import device_manager @@ -75,14 +75,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - def pages(self) -> Iterable[device_manager.ListDeviceRegistriesResponse]: + def pages(self) -> Iterator[device_manager.ListDeviceRegistriesResponse]: 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[resources.DeviceRegistry]: + def __iter__(self) -> Iterator[resources.DeviceRegistry]: for page in self.pages: yield from page.device_registries @@ -137,14 +137,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - async def pages(self) -> AsyncIterable[device_manager.ListDeviceRegistriesResponse]: + async def pages(self) -> AsyncIterator[device_manager.ListDeviceRegistriesResponse]: 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[resources.DeviceRegistry]: + def __aiter__(self) -> AsyncIterator[resources.DeviceRegistry]: async def async_generator(): async for page in self.pages: for response in page.device_registries: @@ -203,14 +203,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - def pages(self) -> Iterable[device_manager.ListDevicesResponse]: + def pages(self) -> Iterator[device_manager.ListDevicesResponse]: 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[resources.Device]: + def __iter__(self) -> Iterator[resources.Device]: for page in self.pages: yield from page.devices @@ -265,14 +265,14 @@ def __getattr__(self, name: str) -> Any: return getattr(self._response, name) @property - async def pages(self) -> AsyncIterable[device_manager.ListDevicesResponse]: + async def pages(self) -> AsyncIterator[device_manager.ListDevicesResponse]: 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[resources.Device]: + def __aiter__(self) -> AsyncIterator[resources.Device]: async def async_generator(): async for page in self.pages: for response in page.devices: diff --git a/google/cloud/iot_v1/services/device_manager/transports/base.py b/google/cloud/iot_v1/services/device_manager/transports/base.py index ae596089..3435d32a 100644 --- a/google/cloud/iot_v1/services/device_manager/transports/base.py +++ b/google/cloud/iot_v1/services/device_manager/transports/base.py @@ -15,14 +15,13 @@ # import abc from typing import Awaitable, Callable, Dict, Optional, Sequence, Union -import packaging.version import pkg_resources import google.auth # type: ignore -import google.api_core # type: ignore -from google.api_core import exceptions as core_exceptions # type: ignore -from google.api_core import gapic_v1 # type: ignore -from google.api_core import retry as retries # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore @@ -39,15 +38,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 DeviceManagerTransport(abc.ABC): """Abstract transport class for DeviceManager.""" @@ -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 @@ -116,7 +106,6 @@ def __init__( credentials, _ = google.auth.load_credentials_from_file( credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) - elif credentials is None: credentials, _ = google.auth.default( **scopes_kwargs, quota_project_id=quota_project_id @@ -133,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 = { @@ -350,6 +316,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 create_device_registry( self, diff --git a/google/cloud/iot_v1/services/device_manager/transports/grpc.py b/google/cloud/iot_v1/services/device_manager/transports/grpc.py index 04b119b6..20675cf3 100644 --- a/google/cloud/iot_v1/services/device_manager/transports/grpc.py +++ b/google/cloud/iot_v1/services/device_manager/transports/grpc.py @@ -16,8 +16,8 @@ import warnings from typing import Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import grpc_helpers # type: ignore -from google.api_core import gapic_v1 # type: ignore +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -163,8 +163,11 @@ def __init__( if not self._grpc_channel: self._grpc_channel = type(self).create_channel( self._host, + # use the credentials which are saved credentials=self._credentials, - credentials_file=credentials_file, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, scopes=self._scopes, ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, @@ -781,5 +784,8 @@ def unbind_device_from_gateway( ) return self._stubs["unbind_device_from_gateway"] + def close(self): + self.grpc_channel.close() + __all__ = ("DeviceManagerGrpcTransport",) diff --git a/google/cloud/iot_v1/services/device_manager/transports/grpc_asyncio.py b/google/cloud/iot_v1/services/device_manager/transports/grpc_asyncio.py index d621cb4d..57d8203e 100644 --- a/google/cloud/iot_v1/services/device_manager/transports/grpc_asyncio.py +++ b/google/cloud/iot_v1/services/device_manager/transports/grpc_asyncio.py @@ -16,11 +16,10 @@ import warnings from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union -from google.api_core import gapic_v1 # type: ignore -from google.api_core import grpc_helpers_async # type: ignore +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async 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 @@ -209,8 +208,11 @@ def __init__( if not self._grpc_channel: self._grpc_channel = type(self).create_channel( self._host, + # use the credentials which are saved credentials=self._credentials, - credentials_file=credentials_file, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, scopes=self._scopes, ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, @@ -792,5 +794,8 @@ def unbind_device_from_gateway( ) return self._stubs["unbind_device_from_gateway"] + def close(self): + return self.grpc_channel.close() + __all__ = ("DeviceManagerGrpcAsyncIOTransport",) diff --git a/google/cloud/iot_v1/types/device_manager.py b/google/cloud/iot_v1/types/device_manager.py index 29ae5f4a..8f4dc0d7 100644 --- a/google/cloud/iot_v1/types/device_manager.py +++ b/google/cloud/iot_v1/types/device_manager.py @@ -52,6 +52,7 @@ class CreateDeviceRegistryRequest(proto.Message): r"""Request for ``CreateDeviceRegistry``. + Attributes: parent (str): Required. The project and cloud region where this device @@ -71,6 +72,7 @@ class CreateDeviceRegistryRequest(proto.Message): class GetDeviceRegistryRequest(proto.Message): r"""Request for ``GetDeviceRegistry``. + Attributes: name (str): Required. The name of the device registry. For example, @@ -82,6 +84,7 @@ class GetDeviceRegistryRequest(proto.Message): class DeleteDeviceRegistryRequest(proto.Message): r"""Request for ``DeleteDeviceRegistry``. + Attributes: name (str): Required. The name of the device registry. For example, @@ -93,6 +96,7 @@ class DeleteDeviceRegistryRequest(proto.Message): class UpdateDeviceRegistryRequest(proto.Message): r"""Request for ``UpdateDeviceRegistry``. + Attributes: device_registry (google.cloud.iot_v1.types.DeviceRegistry): Required. The new values for the device registry. The ``id`` @@ -118,6 +122,7 @@ class UpdateDeviceRegistryRequest(proto.Message): class ListDeviceRegistriesRequest(proto.Message): r"""Request for ``ListDeviceRegistries``. + Attributes: parent (str): Required. The project and cloud region path. For example, @@ -142,6 +147,7 @@ class ListDeviceRegistriesRequest(proto.Message): class ListDeviceRegistriesResponse(proto.Message): r"""Response for ``ListDeviceRegistries``. + Attributes: device_registries (Sequence[google.cloud.iot_v1.types.DeviceRegistry]): The registries that matched the query. @@ -163,6 +169,7 @@ def raw_page(self): class CreateDeviceRequest(proto.Message): r"""Request for ``CreateDevice``. + Attributes: parent (str): Required. The name of the device registry where this device @@ -180,6 +187,7 @@ class CreateDeviceRequest(proto.Message): class GetDeviceRequest(proto.Message): r"""Request for ``GetDevice``. + Attributes: name (str): Required. The name of the device. For example, @@ -199,6 +207,7 @@ class GetDeviceRequest(proto.Message): class UpdateDeviceRequest(proto.Message): r"""Request for ``UpdateDevice``. + Attributes: device (google.cloud.iot_v1.types.Device): Required. The new values for the device. The ``id`` and @@ -222,6 +231,7 @@ class UpdateDeviceRequest(proto.Message): class DeleteDeviceRequest(proto.Message): r"""Request for ``DeleteDevice``. + Attributes: name (str): Required. The name of the device. For example, @@ -235,6 +245,7 @@ class DeleteDeviceRequest(proto.Message): class ListDevicesRequest(proto.Message): r"""Request for ``ListDevices``. + Attributes: parent (str): Required. The device registry path. Required. For example, @@ -281,24 +292,37 @@ class GatewayListOptions(proto.Message): r"""Options for limiting the list based on gateway type and associations. + 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: gateway_type (google.cloud.iot_v1.types.GatewayType): If ``GATEWAY`` is specified, only gateways are returned. If ``NON_GATEWAY`` is specified, only non-gateway devices are returned. If ``GATEWAY_TYPE_UNSPECIFIED`` is specified, all devices are returned. + + This field is a member of `oneof`_ ``filter``. associations_gateway_id (str): If set, only devices associated with the specified gateway are returned. The gateway ID can be numeric (``num_id``) or the user-defined string (``id``). For example, if ``123`` is specified, only devices bound to the gateway with ``num_id`` 123 are returned. + + This field is a member of `oneof`_ ``filter``. associations_device_id (str): If set, returns only the gateways with which the specified device is associated. The device ID can be numeric (``num_id``) or the user-defined string (``id``). For example, if ``456`` is specified, returns only the gateways to which the device with ``num_id`` 456 is bound. + + This field is a member of `oneof`_ ``filter``. """ gateway_type = proto.Field( @@ -310,6 +334,7 @@ class GatewayListOptions(proto.Message): class ListDevicesResponse(proto.Message): r"""Response for ``ListDevices``. + Attributes: devices (Sequence[google.cloud.iot_v1.types.Device]): The devices that match the request. @@ -329,6 +354,7 @@ def raw_page(self): class ModifyCloudToDeviceConfigRequest(proto.Message): r"""Request for ``ModifyCloudToDeviceConfig``. + Attributes: name (str): Required. The name of the device. For example, @@ -356,6 +382,7 @@ class ModifyCloudToDeviceConfigRequest(proto.Message): class ListDeviceConfigVersionsRequest(proto.Message): r"""Request for ``ListDeviceConfigVersions``. + Attributes: name (str): Required. The name of the device. For example, @@ -376,6 +403,7 @@ class ListDeviceConfigVersionsRequest(proto.Message): class ListDeviceConfigVersionsResponse(proto.Message): r"""Response for ``ListDeviceConfigVersions``. + Attributes: device_configs (Sequence[google.cloud.iot_v1.types.DeviceConfig]): The device configuration for the last few @@ -390,6 +418,7 @@ class ListDeviceConfigVersionsResponse(proto.Message): class ListDeviceStatesRequest(proto.Message): r"""Request for ``ListDeviceStates``. + Attributes: name (str): Required. The name of the device. For example, @@ -410,6 +439,7 @@ class ListDeviceStatesRequest(proto.Message): class ListDeviceStatesResponse(proto.Message): r"""Response for ``ListDeviceStates``. + Attributes: device_states (Sequence[google.cloud.iot_v1.types.DeviceState]): The last few device states. States are listed @@ -424,6 +454,7 @@ class ListDeviceStatesResponse(proto.Message): class SendCommandToDeviceRequest(proto.Message): r"""Request for ``SendCommandToDevice``. + Attributes: name (str): Required. The name of the device. For example, @@ -437,12 +468,12 @@ class SendCommandToDeviceRequest(proto.Message): Optional subfolder for the command. If empty, the command will be delivered to the /devices/{device-id}/commands topic, otherwise - it will be delivered to the /devices/{device- - id}/commands/{subfolder} topic. Multi-level - subfolders are allowed. This field must not have - more than 256 characters, and must not contain - any MQTT wildcards ("+" or "#") or null - characters. + it will be delivered to the + /devices/{device-id}/commands/{subfolder} topic. + Multi-level subfolders are allowed. This field + must not have more than 256 characters, and must + not contain any MQTT wildcards ("+" or "#") or + null characters. """ name = proto.Field(proto.STRING, number=1,) @@ -451,11 +482,13 @@ class SendCommandToDeviceRequest(proto.Message): class SendCommandToDeviceResponse(proto.Message): - r"""Response for ``SendCommandToDevice``. """ + r"""Response for ``SendCommandToDevice``. + """ class BindDeviceToGatewayRequest(proto.Message): r"""Request for ``BindDeviceToGateway``. + Attributes: parent (str): Required. The name of the registry. For example, @@ -475,11 +508,13 @@ class BindDeviceToGatewayRequest(proto.Message): class BindDeviceToGatewayResponse(proto.Message): - r"""Response for ``BindDeviceToGateway``. """ + r"""Response for ``BindDeviceToGateway``. + """ class UnbindDeviceFromGatewayRequest(proto.Message): r"""Request for ``UnbindDeviceFromGateway``. + Attributes: parent (str): Required. The name of the registry. For example, @@ -499,7 +534,8 @@ class UnbindDeviceFromGatewayRequest(proto.Message): class UnbindDeviceFromGatewayResponse(proto.Message): - r"""Response for ``UnbindDeviceFromGateway``. """ + r"""Response for ``UnbindDeviceFromGateway``. + """ __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/iot_v1/types/resources.py b/google/cloud/iot_v1/types/resources.py index f2932c13..e8a618d0 100644 --- a/google/cloud/iot_v1/types/resources.py +++ b/google/cloud/iot_v1/types/resources.py @@ -115,6 +115,7 @@ class PublicKeyFormat(proto.Enum): class Device(proto.Message): r"""The device resource. + Attributes: id (str): The user-defined device identifier. The @@ -249,6 +250,7 @@ class Device(proto.Message): class GatewayConfig(proto.Message): r"""Gateway-related configuration and state. + Attributes: gateway_type (google.cloud.iot_v1.types.GatewayType): Indicates whether the device is a gateway. @@ -273,6 +275,7 @@ class GatewayConfig(proto.Message): class DeviceRegistry(proto.Message): r"""A container for a group of devices. + Attributes: id (str): The identifier of this device registry. For example, @@ -353,6 +356,7 @@ class DeviceRegistry(proto.Message): class MqttConfig(proto.Message): r"""The configuration of MQTT for a device registry. + Attributes: mqtt_enabled_state (google.cloud.iot_v1.types.MqttState): If enabled, allows connections using the MQTT @@ -365,6 +369,7 @@ class MqttConfig(proto.Message): class HttpConfig(proto.Message): r"""The configuration of the HTTP bridge for a device registry. + Attributes: http_enabled_state (google.cloud.iot_v1.types.HttpState): If enabled, allows devices to use @@ -378,6 +383,7 @@ class HttpConfig(proto.Message): class EventNotificationConfig(proto.Message): r"""The configuration for forwarding telemetry events. + Attributes: subfolder_matches (str): If the subfolder name matches this string @@ -412,10 +418,15 @@ class RegistryCredential(proto.Message): r"""A server-stored registry credential used to validate device credentials. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: public_key_certificate (google.cloud.iot_v1.types.PublicKeyCertificate): A public key certificate used to verify the device credentials. + + This field is a member of `oneof`_ ``credential``. """ public_key_certificate = proto.Field( @@ -453,6 +464,7 @@ class X509CertificateDetails(proto.Message): class PublicKeyCertificate(proto.Message): r"""A public key certificate format and data. + Attributes: format (google.cloud.iot_v1.types.PublicKeyCertificateFormat): The certificate format. @@ -472,6 +484,9 @@ class PublicKeyCertificate(proto.Message): class DeviceCredential(proto.Message): r"""A server-stored device credential used for authentication. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: public_key (google.cloud.iot_v1.types.PublicKeyCredential): A public key used to verify the signature of @@ -490,6 +505,8 @@ class DeviceCredential(proto.Message): keys will be accepted. New device credentials must be different from every registry-level certificate. + + This field is a member of `oneof`_ ``credential``. expiration_time (google.protobuf.timestamp_pb2.Timestamp): [Optional] The time at which this credential becomes invalid. This credential will be ignored for new client @@ -507,6 +524,7 @@ class DeviceCredential(proto.Message): class PublicKeyCredential(proto.Message): r"""A public key format and data. + Attributes: format (google.cloud.iot_v1.types.PublicKeyFormat): The format of the key. @@ -520,6 +538,7 @@ class PublicKeyCredential(proto.Message): class DeviceConfig(proto.Message): r"""The device configuration. Eventually delivered to devices. + Attributes: version (int): [Output only] The version of this update. The version number @@ -559,6 +578,7 @@ class DeviceConfig(proto.Message): class DeviceState(proto.Message): r"""The device state, as reported by the device. + Attributes: update_time (google.protobuf.timestamp_pb2.Timestamp): [Output only] The time at which this state version was diff --git a/noxfile.py b/noxfile.py index 2bf3ffd7..2a2001c4 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() @@ -101,7 +101,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", @@ -175,7 +175,7 @@ def cover(session): test runs (not system test runs), and then erases coverage data. """ session.install("coverage", "pytest-cov") - session.run("coverage", "report", "--show-missing", "--fail-under=98") + session.run("coverage", "report", "--show-missing", "--fail-under=100") session.run("coverage", "erase") diff --git a/owlbot.py b/owlbot.py index 9d1f5695..5e3c46be 100644 --- a/owlbot.py +++ b/owlbot.py @@ -39,7 +39,7 @@ templated_files = common.py_library( samples=True, microgenerator=True, - cov_level=98, + cov_level=100, ) s.move(templated_files, excludes=[".coveragerc"]) # microgenerator has a good .coveragerc file @@ -51,3 +51,30 @@ s.shell.run(["nox", "-s", "blacken"], hide_output=False) +# ---------------------------------------------------------------------------- +# Repo specifics replacements +# ---------------------------------------------------------------------------- + +s.replace( + "samples/api-client/accesstoken_example/noxfile.py", + "# Copyright 2019 Google LLC", + "# Copyright 2021 Google LLC" +) + +s.replace( + "samples/api-client/mqtt_example/noxfile.py", + "# Copyright 2019 Google LLC", + "# Copyright 2021 Google LLC" +) + +s.replace( + "scripts/readme-gen/templates/*.rst", + "GoogleCloudPlatform/python-docs-samples", + "googleapis/python-iot" +) + +s.replace( + "scripts/readme-gen/templates/*.rst", + "python-docs-samples", + "python-iot" +) diff --git a/samples/AUTHORING_GUIDE.md b/samples/AUTHORING_GUIDE.md index 55c97b32..8249522f 100644 --- a/samples/AUTHORING_GUIDE.md +++ b/samples/AUTHORING_GUIDE.md @@ -1 +1 @@ -See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/AUTHORING_GUIDE.md \ No newline at end of file +See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/AUTHORING_GUIDE.md \ No newline at end of file diff --git a/samples/CONTRIBUTING.md b/samples/CONTRIBUTING.md index 34c882b6..f5fe2e6b 100644 --- a/samples/CONTRIBUTING.md +++ b/samples/CONTRIBUTING.md @@ -1 +1 @@ -See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/CONTRIBUTING.md \ No newline at end of file +See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/CONTRIBUTING.md \ No newline at end of file diff --git a/samples/api-client/accesstoken_example/accesstoken.py b/samples/api-client/accesstoken_example/accesstoken.py index 35073a6f..09414243 100644 --- a/samples/api-client/accesstoken_example/accesstoken.py +++ b/samples/api-client/accesstoken_example/accesstoken.py @@ -42,6 +42,8 @@ import os import time +from google.cloud import pubsub +from google.cloud import storage import jwt import requests as req @@ -127,18 +129,16 @@ def publish_pubsub_message( rsa_private_key_path, ) - # Create Pub/Sub topic - request_path = "https://pubsub.googleapis.com/v1/projects/{}/topics/{}".format( - project_id, topic_id - ) + pubsub_client = pubsub.PublisherClient() + topic_path = pubsub_client.topic_path(project_id, topic_id) + pubsub_client.create_topic(request={"name": topic_path}) + print("Successfully created Pub/Sub topic: {}.".format(topic_id)) + headers = { "Authorization": "Bearer {}".format(access_token), "content-type": "application/json", "cache-control": "no-cache", } - resp = req.put(url=request_path, data={}, headers=headers) - assert resp.ok, resp.raise_for_status() - print("Successfully created Pub/Sub topic: {}.".format(topic_id)) # Publish message to Pub/Sub topic publish_payload = { @@ -160,11 +160,7 @@ def publish_pubsub_message( ) # Delete Pub/Sub topic - pubsub_delete_request_path = "https://pubsub.googleapis.com/v1/projects/{}/topics/{}".format( - project_id, topic_id - ) - delete_resp = req.delete(url=pubsub_delete_request_path, headers=headers) - assert delete_resp.ok, delete_resp.raise_for_status() + pubsub_client.delete_topic(request={"topic": topic_path}) print("Successfully deleted Pub/Sub topic: {}".format(topic_id)) # [END iot_access_token_pubsub] @@ -202,27 +198,18 @@ def download_cloud_storage_file( rsa_private_key_path, ) - # Create GCS bucket - create_payload = { - "name": bucket_name, - "location": cloud_region, - "storageClass": "STANDARD", - "iamConfiguration": {"uniformBucketLevelAccess": {"enabled": True}}, - } - create_request_path = "https://storage.googleapis.com/storage/v1/b?project={}".format( - project_id - ) headers = { "authorization": "Bearer {}".format(access_token), "content-type": "application/json", "cache-control": "no-cache", } - create_resp = req.post( - url=create_request_path, - data=bytes(json.dumps(create_payload), "utf-8"), - headers=headers, - ) - assert create_resp.ok, create_resp.raise_for_status() + + # Create GCS bucket + storage_client = storage.Client() + bucket = storage_client.bucket(bucket_name) + bucket.storage_class = "COLDLINE" + bucket.iam_configuration.uniform_bucket_level_access_enabled = True + storage_client.create_bucket(bucket, location=cloud_region) print("Successfully created Storage bucket: {}".format(bucket_name)) # Upload data to GCS bucket. @@ -232,6 +219,7 @@ def download_cloud_storage_file( bucket_name, data_name ) upload_resp = req.post(url=upload_request_path, data=binary_data, headers=headers) + print("Upload response: ", upload_resp.json()) assert upload_resp.ok, upload_resp.raise_for_status() print( "Successfully uploaded {} as {} to bucket {}.".format( @@ -248,19 +236,12 @@ def download_cloud_storage_file( print("Successfully downloaded {} from bucket {}.".format(data_name, bucket_name)) # Delete data from GCS bucket. - delete_request_path = "https://storage.googleapis.com/storage/v1/b/{}/o/{}".format( - bucket_name, data_name - ) - delete_data_resp = req.delete(url=delete_request_path, headers=headers) - assert delete_data_resp.ok, delete_data_resp.raise_for_status() + blob = bucket.blob(data_name) + blob.delete() print("Successfully deleted {} from bucket {}.".format(data_name, bucket_name)) # Delete GCS Bucket - gcs_delete_request_path = "https://storage.googleapis.com/storage/v1/b/{}".format( - bucket_name - ) - delete_resp = req.delete(url=gcs_delete_request_path, headers=headers) - assert delete_resp.ok, delete_resp.raise_for_status() + bucket.delete() print("Successfully deleted bucket: {}".format(bucket_name)) # [END iot_access_token_gcs] diff --git a/samples/api-client/accesstoken_example/noxfile.py b/samples/api-client/accesstoken_example/noxfile.py index b008613f..3637109c 100644 --- a/samples/api-client/accesstoken_example/noxfile.py +++ b/samples/api-client/accesstoken_example/noxfile.py @@ -1,4 +1,4 @@ -# Copyright 2019 Google LLC +# Copyright 2021 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,6 +14,7 @@ from __future__ import print_function +import glob import os from pathlib import Path import sys @@ -87,7 +88,7 @@ def get_pytest_env_vars() -> Dict[str, str]: # DO NOT EDIT - automatically generated. # All versions used to test samples. -ALL_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] +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"] @@ -98,6 +99,10 @@ def get_pytest_env_vars() -> Dict[str, str]: "True", "true", ) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + # # Style Checks # @@ -180,37 +185,45 @@ def blacken(session: nox.sessions.Session) -> 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}") - """Runs py.test for a particular project.""" - if os.path.exists("requirements.txt"): - if os.path.exists("constraints.txt"): - session.install("-r", "requirements.txt", "-c", "constraints.txt") - else: - session.install("-r", "requirements.txt") - - if os.path.exists("requirements-test.txt"): - if os.path.exists("constraints-test.txt"): - session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") - else: - session.install("-r", "requirements-test.txt") - - if INSTALL_LIBRARY_FROM_SOURCE: - session.install("-e", _get_repo_root()) - - if post_install: - post_install(session) - - session.run( - "pytest", - *(PYTEST_COMMON_ARGS + session.posargs), - # Pytest will return 5 when no tests are collected. This can happen - # 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(), - ) + # check for presence of tests + test_list = glob.glob("*_test.py") + glob.glob("test_*.py") + test_list.extend(glob.glob("tests")) + if len(test_list) == 0: + print("No tests found, skipping directory.") + else: + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install( + "-r", "requirements-test.txt", "-c", "constraints-test.txt" + ) + else: + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # 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(), + ) @nox.session(python=ALL_VERSIONS) diff --git a/samples/api-client/accesstoken_example/requirements-test.txt b/samples/api-client/accesstoken_example/requirements-test.txt index a25b6ec6..1a1b18d2 100644 --- a/samples/api-client/accesstoken_example/requirements-test.txt +++ b/samples/api-client/accesstoken_example/requirements-test.txt @@ -1,3 +1,3 @@ -pytest==6.2.4 -google-cloud-pubsub==1.7.0 -google-cloud-storage==1.42.0 +pytest==7.0.1 +google-cloud-pubsub==2.9.0 +google-cloud-storage==2.1.0 diff --git a/samples/api-client/accesstoken_example/requirements.txt b/samples/api-client/accesstoken_example/requirements.txt index 0c50fb04..68085ae5 100644 --- a/samples/api-client/accesstoken_example/requirements.txt +++ b/samples/api-client/accesstoken_example/requirements.txt @@ -1,10 +1,10 @@ -cryptography==3.4.7 +cryptography==36.0.1 flaky==3.7.0 -google-api-python-client==2.10.0 +google-api-python-client==2.38.0 google-auth-httplib2==0.1.0 -google-auth==1.32.1 -google-cloud-iot==2.1.0 -google-cloud-pubsub==1.7.0 -google-cloud-storage==1.42.0 -paho-mqtt==1.5.1 -pyjwt==2.1.0 +google-auth==2.6.0 +google-cloud-iot==2.3.0 +google-cloud-pubsub==2.9.0 +google-cloud-storage==2.1.0 +paho-mqtt==1.6.1 +pyjwt==2.3.0 diff --git a/samples/api-client/manager/manager.py b/samples/api-client/manager/manager.py index 260d7134..5b4c12a6 100644 --- a/samples/api-client/manager/manager.py +++ b/samples/api-client/manager/manager.py @@ -48,15 +48,15 @@ def create_iot_topic(project, topic_name): pubsub_client = pubsub.PublisherClient() topic_path = pubsub_client.topic_path(project, topic_name) - topic = pubsub_client.create_topic(topic_path) - policy = pubsub_client.get_iam_policy(topic_path) + topic = pubsub_client.create_topic(request={"name": topic_path}) + policy = pubsub_client.get_iam_policy(request={"resource": topic_path}) policy.bindings.add( role="roles/pubsub.publisher", members=["serviceAccount:cloud-iot@system.gserviceaccount.com"], ) - pubsub_client.set_iam_policy(topic_path, policy) + pubsub_client.set_iam_policy(request={"resource": topic_path, "policy": policy}) return topic diff --git a/samples/api-client/manager/manager_test.py b/samples/api-client/manager/manager_test.py index e8300fc4..3ced5372 100644 --- a/samples/api-client/manager/manager_test.py +++ b/samples/api-client/manager/manager_test.py @@ -148,7 +148,7 @@ def test_topic(): pubsub_client = pubsub.PublisherClient() topic_path = pubsub_client.topic_path(project_id, topic_id) - pubsub_client.delete_topic(topic_path) + pubsub_client.delete_topic(request={"topic": topic_path}) def test_create_delete_registry(test_topic, capsys): diff --git a/samples/api-client/manager/noxfile.py b/samples/api-client/manager/noxfile.py index b008613f..20cdfc62 100644 --- a/samples/api-client/manager/noxfile.py +++ b/samples/api-client/manager/noxfile.py @@ -14,6 +14,7 @@ from __future__ import print_function +import glob import os from pathlib import Path import sys @@ -87,7 +88,7 @@ def get_pytest_env_vars() -> Dict[str, str]: # DO NOT EDIT - automatically generated. # All versions used to test samples. -ALL_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] +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"] @@ -98,6 +99,10 @@ def get_pytest_env_vars() -> Dict[str, str]: "True", "true", ) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + # # Style Checks # @@ -180,37 +185,45 @@ def blacken(session: nox.sessions.Session) -> 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}") - """Runs py.test for a particular project.""" - if os.path.exists("requirements.txt"): - if os.path.exists("constraints.txt"): - session.install("-r", "requirements.txt", "-c", "constraints.txt") - else: - session.install("-r", "requirements.txt") - - if os.path.exists("requirements-test.txt"): - if os.path.exists("constraints-test.txt"): - session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") - else: - session.install("-r", "requirements-test.txt") - - if INSTALL_LIBRARY_FROM_SOURCE: - session.install("-e", _get_repo_root()) - - if post_install: - post_install(session) - - session.run( - "pytest", - *(PYTEST_COMMON_ARGS + session.posargs), - # Pytest will return 5 when no tests are collected. This can happen - # 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(), - ) + # check for presence of tests + test_list = glob.glob("*_test.py") + glob.glob("test_*.py") + test_list.extend(glob.glob("tests")) + if len(test_list) == 0: + print("No tests found, skipping directory.") + else: + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install( + "-r", "requirements-test.txt", "-c", "constraints-test.txt" + ) + else: + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # 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(), + ) @nox.session(python=ALL_VERSIONS) diff --git a/samples/api-client/manager/requirements-test.txt b/samples/api-client/manager/requirements-test.txt index 92709451..c2845bff 100644 --- a/samples/api-client/manager/requirements-test.txt +++ b/samples/api-client/manager/requirements-test.txt @@ -1 +1 @@ -pytest==6.2.5 +pytest==7.0.1 diff --git a/samples/api-client/manager/requirements.txt b/samples/api-client/manager/requirements.txt index b94bf0e7..96774b88 100644 --- a/samples/api-client/manager/requirements.txt +++ b/samples/api-client/manager/requirements.txt @@ -1,9 +1,9 @@ -cryptography==3.4.8 +cryptography==36.0.1 flaky==3.7.0 -google-api-python-client==2.19.0 +google-api-python-client==2.38.0 google-auth-httplib2==0.1.0 -google-auth==2.0.2 -google-cloud-iot==2.2.1 -google-cloud-pubsub==1.7.0 -paho-mqtt==1.5.1 -pyjwt==2.1.0 +google-auth==2.6.0 +google-cloud-iot==2.3.0 +google-cloud-pubsub==2.9.0 +paho-mqtt==1.6.1 +pyjwt==2.3.0 diff --git a/samples/api-client/mqtt_example/README.rst b/samples/api-client/mqtt_example/README.rst new file mode 100644 index 00000000..c11ed15a --- /dev/null +++ b/samples/api-client/mqtt_example/README.rst @@ -0,0 +1,151 @@ +.. This file is automatically generated. Do not edit this file directly. + +Google Cloud IoT Core Python Samples +=============================================================================== + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/python-iot&page=editor&open_in_editor=iot/api-client/mqtt_example/README.rst + + +This directory contains samples for `Google Cloud IoT Core`_. Cloud IoT Core allows developers to easily integrate Publish and Subscribe functionality with devices and programmatically manage device authorization. +This example connects a device to Cloud IoT Core via MQTT, using a JWT for authentication. After connecting, the device publishes messages to the device's MQTT topic at a rate of one per second. +Note that before you can run this sample, you must register a device as described in the `Cloud IoT device docs `_. For the gateway samples, you must register and bind a device as described in the `Cloud IoT gateway docs `_. + + + + +.. _Google Cloud IoT Core: https://cloud.google.com/iot/docs + + + + + +Setup +------------------------------------------------------------------------------- + + +Authentication +++++++++++++++ + +This sample requires you to have authentication setup. Refer to the +`Authentication Getting Started Guide`_ for instructions on setting up +credentials for applications. + +.. _Authentication Getting Started Guide: + https://cloud.google.com/docs/authentication/getting-started + +Install Dependencies +++++++++++++++++++++ + +#. Clone python-iot and change directory to the sample directory you want to use. + + .. code-block:: bash + + $ git clone https://github.com/googleapis/python-iot.git + +#. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions. + + .. _Python Development Environment Setup Guide: + https://cloud.google.com/python/setup + +#. Create a virtualenv. Samples are compatible with Python 3.6+. + + .. code-block:: bash + + $ virtualenv env + $ source env/bin/activate + +#. Install the dependencies needed to run the samples. + + .. code-block:: bash + + $ pip install -r requirements.txt + +.. _pip: https://pip.pypa.io/ +.. _virtualenv: https://virtualenv.pypa.io/ + +Samples +------------------------------------------------------------------------------- + +MQTT example ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/python-iot&page=editor&open_in_editor=iot/api-client/mqtt_example/cloudiot_mqtt_example.py,iot/api-client/mqtt_example/README.rst + + + + +To run this sample: + +.. code-block:: no-highlight + + $ python cloudiot_mqtt_example.py + + usage: cloudiot_mqtt_example.py [-h] --algorithm {RS256,ES256} + [--ca_certs CA_CERTS] + [--cloud_region CLOUD_REGION] [--data DATA] + --device_id DEVICE_ID + [--gateway_id GATEWAY_ID] + [--jwt_expires_minutes JWT_EXPIRES_MINUTES] + [--listen_dur LISTEN_DUR] + [--message_type {event,state}] + [--mqtt_bridge_hostname MQTT_BRIDGE_HOSTNAME] + [--mqtt_bridge_port {8883,443}] + [--num_messages NUM_MESSAGES] + --private_key_file PRIVATE_KEY_FILE + [--project_id PROJECT_ID] --registry_id + REGISTRY_ID + [--service_account_json SERVICE_ACCOUNT_JSON] + {device_demo,gateway_send,gateway_listen} ... + + Example Google Cloud IoT Core MQTT device connection code. + + positional arguments: + {device_demo,gateway_send,gateway_listen} + device_demo Connects a device, sends data, and receives data. + gateway_send Sends data from a gateway on behalf of a device that + is bound to it. + gateway_listen Listens for messages sent to the gateway and bound + devices. + + optional arguments: + -h, --help show this help message and exit + --algorithm {RS256,ES256} + Which encryption algorithm to use to generate the JWT. + --ca_certs CA_CERTS CA root from https://pki.google.com/roots.pem + --cloud_region CLOUD_REGION + GCP cloud region + --data DATA The telemetry data sent on behalf of a device + --device_id DEVICE_ID + Cloud IoT Core device id + --gateway_id GATEWAY_ID + Gateway identifier. + --jwt_expires_minutes JWT_EXPIRES_MINUTES + Expiration time, in minutes, for JWT tokens. + --listen_dur LISTEN_DUR + Duration (seconds) to listen for configuration + messages + --message_type {event,state} + Indicates whether the message to be published is a + telemetry event or a device state message. + --mqtt_bridge_hostname MQTT_BRIDGE_HOSTNAME + MQTT bridge hostname. + --mqtt_bridge_port {8883,443} + MQTT bridge port. + --num_messages NUM_MESSAGES + Number of messages to publish. + --private_key_file PRIVATE_KEY_FILE + Path to private key file. + --project_id PROJECT_ID + GCP cloud project name + --registry_id REGISTRY_ID + Cloud IoT Core registry id + --service_account_json SERVICE_ACCOUNT_JSON + Path to service account json file. + + + + + +.. _Google Cloud SDK: https://cloud.google.com/sdk/ \ No newline at end of file diff --git a/samples/api-client/mqtt_example/README.rst.in b/samples/api-client/mqtt_example/README.rst.in new file mode 100644 index 00000000..842e76e1 --- /dev/null +++ b/samples/api-client/mqtt_example/README.rst.in @@ -0,0 +1,32 @@ +# This file is used to generate README.rst + +product: + name: Google Cloud IoT Core + short_name: Cloud IoT Core + url: https://cloud.google.com/iot/docs + description: > + Cloud IoT Core allows developers to easily integrate Publish and + Subscribe functionality with devices and programmatically manage device + authorization. + + This example connects a device to Cloud IoT Core via MQTT, using a JWT for + authentication. After connecting, the device publishes messages to the device's + MQTT topic at a rate of one per second. + + Note that before you can run this sample, you must register a device as described + in the `Cloud IoT device docs `_. + For the gateway samples, you must register and bind a device as described in the + `Cloud IoT gateway docs `_. + +setup: +- auth +- install_deps + +samples: +- name: MQTT example + file: cloudiot_mqtt_example.py + show_help: True + +cloud_client_library: false + +folder: iot/api-client/mqtt_example diff --git a/samples/api-client/mqtt_example/cloudiot_mqtt_example.py b/samples/api-client/mqtt_example/cloudiot_mqtt_example.py index 70085a78..b52107c9 100644 --- a/samples/api-client/mqtt_example/cloudiot_mqtt_example.py +++ b/samples/api-client/mqtt_example/cloudiot_mqtt_example.py @@ -32,9 +32,10 @@ import jwt import paho.mqtt.client as mqtt + # [END iot_mqtt_includes] -logging.getLogger('googleapiclient.discovery_cache').setLevel(logging.CRITICAL) +logging.getLogger("googleapiclient.discovery_cache").setLevel(logging.CRITICAL) # The initial backoff time after a disconnection occurs, in seconds. minimum_backoff_time = 1 @@ -63,34 +64,39 @@ def create_jwt(project_id, private_key_file, algorithm): """ token = { - # The time that the token was issued at - 'iat': datetime.datetime.utcnow(), - # The time the token expires. - 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=20), - # The audience field should always be set to the GCP project id. - 'aud': project_id + # The time that the token was issued at + "iat": datetime.datetime.utcnow(), + # The time the token expires. + "exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=20), + # The audience field should always be set to the GCP project id. + "aud": project_id, } # Read the private key file. - with open(private_key_file, 'r') as f: + with open(private_key_file, "r") as f: private_key = f.read() - print('Creating JWT using {} from private key file {}'.format( - algorithm, private_key_file)) + print( + "Creating JWT using {} from private key file {}".format( + algorithm, private_key_file + ) + ) return jwt.encode(token, private_key, algorithm=algorithm) + + # [END iot_mqtt_jwt] # [START iot_mqtt_config] def error_str(rc): """Convert a Paho error to a human readable string.""" - return '{}: {}'.format(rc, mqtt.error_string(rc)) + return "{}: {}".format(rc, mqtt.error_string(rc)) def on_connect(unused_client, unused_userdata, unused_flags, rc): """Callback for when a device connects.""" - print('on_connect', mqtt.connack_string(rc)) + print("on_connect", mqtt.connack_string(rc)) # After a successful connect, reset backoff time and stop backing off. global should_backoff @@ -101,7 +107,7 @@ def on_connect(unused_client, unused_userdata, unused_flags, rc): def on_disconnect(unused_client, unused_userdata, rc): """Paho callback for when a device disconnects.""" - print('on_disconnect', error_str(rc)) + print("on_disconnect", error_str(rc)) # Since a disconnect occurred, the next loop iteration will wait with # exponential backoff. @@ -111,33 +117,47 @@ def on_disconnect(unused_client, unused_userdata, rc): def on_publish(unused_client, unused_userdata, unused_mid): """Paho callback when a message is sent to the broker.""" - print('on_publish') + print("on_publish") def on_message(unused_client, unused_userdata, message): """Callback when the device receives a message on a subscription.""" - payload = str(message.payload.decode('utf-8')) - print('Received message \'{}\' on topic \'{}\' with Qos {}'.format( - payload, message.topic, str(message.qos))) + payload = str(message.payload.decode("utf-8")) + print( + "Received message '{}' on topic '{}' with Qos {}".format( + payload, message.topic, str(message.qos) + ) + ) def get_client( - project_id, cloud_region, registry_id, device_id, private_key_file, - algorithm, ca_certs, mqtt_bridge_hostname, mqtt_bridge_port): - """Create our MQTT client. The client_id is a unique string that identifies - this device. For Google Cloud IoT Core, it must be in the format below.""" - client_id = 'projects/{}/locations/{}/registries/{}/devices/{}'.format( - project_id, cloud_region, registry_id, device_id) - print('Device client_id is \'{}\''.format(client_id)) + project_id, + cloud_region, + registry_id, + device_id, + private_key_file, + algorithm, + ca_certs, + mqtt_bridge_hostname, + mqtt_bridge_port, +): + """Create our MQTT client. + + The client_id is a unique string that identifies this device. + For Google Cloud IoT Core, it must be in the format below. + """ + client_id = "projects/{}/locations/{}/registries/{}/devices/{}".format( + project_id, cloud_region, registry_id, device_id + ) + print("Device client_id is '{}'".format(client_id)) client = mqtt.Client(client_id=client_id) # With Google Cloud IoT Core, the username field is ignored, and the # password field is used to transmit a JWT to authorize the device. client.username_pw_set( - username='unused', - password=create_jwt( - project_id, private_key_file, algorithm)) + username="unused", password=create_jwt(project_id, private_key_file, algorithm) + ) # Enable SSL/TLS support. client.tls_set(ca_certs=ca_certs, tls_version=ssl.PROTOCOL_TLSv1_2) @@ -154,45 +174,59 @@ def get_client( client.connect(mqtt_bridge_hostname, mqtt_bridge_port) # This is the topic that the device will receive configuration updates on. - mqtt_config_topic = '/devices/{}/config'.format(device_id) + mqtt_config_topic = "/devices/{}/config".format(device_id) # Subscribe to the config topic. client.subscribe(mqtt_config_topic, qos=1) # The topic that the device will receive commands on. - mqtt_command_topic = '/devices/{}/commands/#'.format(device_id) + mqtt_command_topic = "/devices/{}/commands/#".format(device_id) # Subscribe to the commands topic, QoS 1 enables message acknowledgement. - print('Subscribing to {}'.format(mqtt_command_topic)) + print("Subscribing to {}".format(mqtt_command_topic)) client.subscribe(mqtt_command_topic, qos=0) return client + + # [END iot_mqtt_config] def detach_device(client, device_id): """Detach the device from the gateway.""" # [START iot_detach_device] - detach_topic = '/devices/{}/detach'.format(device_id) - print('Detaching: {}'.format(detach_topic)) - client.publish(detach_topic, '{}', qos=1) + detach_topic = "/devices/{}/detach".format(device_id) + print("Detaching: {}".format(detach_topic)) + client.publish(detach_topic, "{}", qos=1) # [END iot_detach_device] def attach_device(client, device_id, auth): """Attach the device to the gateway.""" # [START iot_attach_device] - attach_topic = '/devices/{}/attach'.format(device_id) + attach_topic = "/devices/{}/attach".format(device_id) attach_payload = '{{"authorization" : "{}"}}'.format(auth) client.publish(attach_topic, attach_payload, qos=1) # [END iot_attach_device] def listen_for_messages( - service_account_json, project_id, cloud_region, registry_id, device_id, - gateway_id, num_messages, private_key_file, algorithm, ca_certs, - mqtt_bridge_hostname, mqtt_bridge_port, jwt_expires_minutes, duration, - cb=None): + service_account_json, + project_id, + cloud_region, + registry_id, + device_id, + gateway_id, + num_messages, + private_key_file, + algorithm, + ca_certs, + mqtt_bridge_hostname, + mqtt_bridge_port, + jwt_expires_minutes, + duration, + cb=None, +): """Listens for messages sent to the gateway and bound devices.""" # [START iot_listen_for_messages] global minimum_backoff_time @@ -201,24 +235,31 @@ def listen_for_messages( jwt_exp_mins = jwt_expires_minutes # Use gateway to connect to server client = get_client( - project_id, cloud_region, registry_id, gateway_id, - private_key_file, algorithm, ca_certs, mqtt_bridge_hostname, - mqtt_bridge_port) - - attach_device(client, device_id, '') - print('Waiting for device to attach.') + project_id, + cloud_region, + registry_id, + gateway_id, + private_key_file, + algorithm, + ca_certs, + mqtt_bridge_hostname, + mqtt_bridge_port, + ) + + attach_device(client, device_id, "") + print("Waiting for device to attach.") time.sleep(5) # The topic devices receive configuration updates on. - device_config_topic = '/devices/{}/config'.format(device_id) + device_config_topic = "/devices/{}/config".format(device_id) client.subscribe(device_config_topic, qos=1) # The topic gateways receive configuration updates on. - gateway_config_topic = '/devices/{}/config'.format(gateway_id) + gateway_config_topic = "/devices/{}/config".format(gateway_id) client.subscribe(gateway_config_topic, qos=1) # The topic gateways receive error updates on. QoS must be 0. - error_topic = '/devices/{}/errors'.format(gateway_id) + error_topic = "/devices/{}/errors".format(gateway_id) client.subscribe(error_topic, qos=0) # Wait for about a minute for config messages. @@ -230,7 +271,7 @@ def listen_for_messages( if should_backoff: # If backoff time is too large, give up. if minimum_backoff_time > MAXIMUM_BACKOFF_TIME: - print('Exceeded maximum backoff time. Giving up.') + print("Exceeded maximum backoff time. Giving up.") break delay = minimum_backoff_time + random.randint(0, 1000) / 1000.0 @@ -240,49 +281,75 @@ def listen_for_messages( seconds_since_issue = (datetime.datetime.utcnow() - jwt_iat).seconds if seconds_since_issue > 60 * jwt_exp_mins: - print('Refreshing token after {}s'.format(seconds_since_issue)) + print("Refreshing token after {}s".format(seconds_since_issue)) jwt_iat = datetime.datetime.utcnow() client.loop() client.disconnect() client = get_client( - project_id, cloud_region, registry_id, gateway_id, - private_key_file, algorithm, ca_certs, mqtt_bridge_hostname, - mqtt_bridge_port) + project_id, + cloud_region, + registry_id, + gateway_id, + private_key_file, + algorithm, + ca_certs, + mqtt_bridge_hostname, + mqtt_bridge_port, + ) time.sleep(1) detach_device(client, device_id) - print('Finished.') + print("Finished.") # [END iot_listen_for_messages] def send_data_from_bound_device( - service_account_json, project_id, cloud_region, registry_id, device_id, - gateway_id, num_messages, private_key_file, algorithm, ca_certs, - mqtt_bridge_hostname, mqtt_bridge_port, jwt_expires_minutes, payload): + service_account_json, + project_id, + cloud_region, + registry_id, + device_id, + gateway_id, + num_messages, + private_key_file, + algorithm, + ca_certs, + mqtt_bridge_hostname, + mqtt_bridge_port, + jwt_expires_minutes, + payload, +): """Sends data from a gateway on behalf of a device that is bound to it.""" # [START send_data_from_bound_device] global minimum_backoff_time # Publish device events and gateway state. - device_topic = '/devices/{}/{}'.format(device_id, 'state') - gateway_topic = '/devices/{}/{}'.format(gateway_id, 'state') + device_topic = "/devices/{}/{}".format(device_id, "state") + gateway_topic = "/devices/{}/{}".format(gateway_id, "state") jwt_iat = datetime.datetime.utcnow() jwt_exp_mins = jwt_expires_minutes # Use gateway to connect to server client = get_client( - project_id, cloud_region, registry_id, gateway_id, - private_key_file, algorithm, ca_certs, mqtt_bridge_hostname, - mqtt_bridge_port) - - attach_device(client, device_id, '') - print('Waiting for device to attach.') + project_id, + cloud_region, + registry_id, + gateway_id, + private_key_file, + algorithm, + ca_certs, + mqtt_bridge_hostname, + mqtt_bridge_port, + ) + + attach_device(client, device_id, "") + print("Waiting for device to attach.") time.sleep(5) # Publish state to gateway topic - gateway_state = 'Starting gateway at: {}'.format(time.time()) + gateway_state = "Starting gateway at: {}".format(time.time()) print(gateway_state) client.publish(gateway_topic, gateway_state, qos=1) @@ -293,7 +360,7 @@ def send_data_from_bound_device( if should_backoff: # If backoff time is too large, give up. if minimum_backoff_time > MAXIMUM_BACKOFF_TIME: - print('Exceeded maximum backoff time. Giving up.') + print("Exceeded maximum backoff time. Giving up.") break delay = minimum_backoff_time + random.randint(0, 1000) / 1000.0 @@ -301,114 +368,126 @@ def send_data_from_bound_device( minimum_backoff_time *= 2 client.connect(mqtt_bridge_hostname, mqtt_bridge_port) - payload = '{}/{}-{}-payload-{}'.format( - registry_id, gateway_id, device_id, i) + payload = "{}/{}-{}-payload-{}".format(registry_id, gateway_id, device_id, i) - print('Publishing message {}/{}: \'{}\' to {}'.format( - i, num_messages, payload, device_topic)) - client.publish( - device_topic, '{} : {}'.format(device_id, payload), qos=1) + print( + "Publishing message {}/{}: '{}' to {}".format( + i, num_messages, payload, device_topic + ) + ) + client.publish(device_topic, "{} : {}".format(device_id, payload), qos=1) seconds_since_issue = (datetime.datetime.utcnow() - jwt_iat).seconds if seconds_since_issue > 60 * jwt_exp_mins: - print('Refreshing token after {}s').format(seconds_since_issue) + print("Refreshing token after {}s").format(seconds_since_issue) jwt_iat = datetime.datetime.utcnow() client = get_client( - project_id, cloud_region, registry_id, gateway_id, - private_key_file, algorithm, ca_certs, mqtt_bridge_hostname, - mqtt_bridge_port) + project_id, + cloud_region, + registry_id, + gateway_id, + private_key_file, + algorithm, + ca_certs, + mqtt_bridge_hostname, + mqtt_bridge_port, + ) time.sleep(5) detach_device(client, device_id) - print('Finished.') + print("Finished.") # [END send_data_from_bound_device] def parse_command_line_args(): """Parse command line arguments.""" - parser = argparse.ArgumentParser(description=( - 'Example Google Cloud IoT Core MQTT device connection code.')) - parser.add_argument( - '--algorithm', - choices=('RS256', 'ES256'), - required=True, - help='Which encryption algorithm to use to generate the JWT.') - parser.add_argument( - '--ca_certs', - default='roots.pem', - help='CA root from https://pki.google.com/roots.pem') + parser = argparse.ArgumentParser( + description=("Example Google Cloud IoT Core MQTT device connection code.") + ) parser.add_argument( - '--cloud_region', default='us-central1', help='GCP cloud region') + "--algorithm", + choices=("RS256", "ES256"), + required=True, + help="Which encryption algorithm to use to generate the JWT.", + ) parser.add_argument( - '--data', - default='Hello there', - help='The telemetry data sent on behalf of a device') + "--ca_certs", + default="roots.pem", + help="CA root from https://pki.google.com/roots.pem", + ) parser.add_argument( - '--device_id', required=True, help='Cloud IoT Core device id') + "--cloud_region", default="us-central1", help="GCP cloud region" + ) parser.add_argument( - '--gateway_id', required=False, help='Gateway identifier.') + "--data", + default="Hello there", + help="The telemetry data sent on behalf of a device", + ) + parser.add_argument("--device_id", required=True, help="Cloud IoT Core device id") + parser.add_argument("--gateway_id", required=False, help="Gateway identifier.") parser.add_argument( - '--jwt_expires_minutes', - default=20, - type=int, - help='Expiration time, in minutes, for JWT tokens.') + "--jwt_expires_minutes", + default=20, + type=int, + help="Expiration time, in minutes, for JWT tokens.", + ) parser.add_argument( - '--listen_dur', - default=60, - type=int, - help='Duration (seconds) to listen for configuration messages') + "--listen_dur", + default=60, + type=int, + help="Duration (seconds) to listen for configuration messages", + ) parser.add_argument( - '--message_type', - choices=('event', 'state'), - default='event', - help=('Indicates whether the message to be published is a ' - 'telemetry event or a device state message.')) + "--message_type", + choices=("event", "state"), + default="event", + help=( + "Indicates whether the message to be published is a " + "telemetry event or a device state message." + ), + ) parser.add_argument( - '--mqtt_bridge_hostname', - default='mqtt.googleapis.com', - help='MQTT bridge hostname.') + "--mqtt_bridge_hostname", + default="mqtt.googleapis.com", + help="MQTT bridge hostname.", + ) parser.add_argument( - '--mqtt_bridge_port', - choices=(8883, 443), - default=8883, - type=int, - help='MQTT bridge port.') + "--mqtt_bridge_port", + choices=(8883, 443), + default=8883, + type=int, + help="MQTT bridge port.", + ) parser.add_argument( - '--num_messages', - type=int, - default=100, - help='Number of messages to publish.') + "--num_messages", type=int, default=100, help="Number of messages to publish." + ) parser.add_argument( - '--private_key_file', - required=True, - help='Path to private key file.') + "--private_key_file", required=True, help="Path to private key file." + ) parser.add_argument( - '--project_id', - default=os.environ.get('GOOGLE_CLOUD_PROJECT'), - help='GCP cloud project name') + "--project_id", + default=os.environ.get("GOOGLE_CLOUD_PROJECT"), + help="GCP cloud project name", + ) parser.add_argument( - '--registry_id', required=True, help='Cloud IoT Core registry id') + "--registry_id", required=True, help="Cloud IoT Core registry id" + ) parser.add_argument( - '--service_account_json', - default=os.environ.get("GOOGLE_APPLICATION_CREDENTIALS"), - help='Path to service account json file.') + "--service_account_json", + default=os.environ.get("GOOGLE_APPLICATION_CREDENTIALS"), + help="Path to service account json file.", + ) # Command subparser - command = parser.add_subparsers(dest='command') + command = parser.add_subparsers(dest="command") - command.add_parser( - 'device_demo', - help=mqtt_device_demo.__doc__) + command.add_parser("device_demo", help=mqtt_device_demo.__doc__) - command.add_parser( - 'gateway_send', - help=send_data_from_bound_device.__doc__) + command.add_parser("gateway_send", help=send_data_from_bound_device.__doc__) - command.add_parser( - 'gateway_listen', - help=listen_for_messages.__doc__) + command.add_parser("gateway_listen", help=listen_for_messages.__doc__) return parser.parse_args() @@ -420,16 +499,23 @@ def mqtt_device_demo(args): global MAXIMUM_BACKOFF_TIME # Publish to the events or state topic based on the flag. - sub_topic = 'events' if args.message_type == 'event' else 'state' + sub_topic = "events" if args.message_type == "event" else "state" - mqtt_topic = '/devices/{}/{}'.format(args.device_id, sub_topic) + mqtt_topic = "/devices/{}/{}".format(args.device_id, sub_topic) jwt_iat = datetime.datetime.utcnow() jwt_exp_mins = args.jwt_expires_minutes client = get_client( - args.project_id, args.cloud_region, args.registry_id, - args.device_id, args.private_key_file, args.algorithm, - args.ca_certs, args.mqtt_bridge_hostname, args.mqtt_bridge_port) + args.project_id, + args.cloud_region, + args.registry_id, + args.device_id, + args.private_key_file, + args.algorithm, + args.ca_certs, + args.mqtt_bridge_hostname, + args.mqtt_bridge_port, + ) # Publish num_messages messages to the MQTT bridge once per second. for i in range(1, args.num_messages + 1): @@ -440,32 +526,36 @@ def mqtt_device_demo(args): if should_backoff: # If backoff time is too large, give up. if minimum_backoff_time > MAXIMUM_BACKOFF_TIME: - print('Exceeded maximum backoff time. Giving up.') + print("Exceeded maximum backoff time. Giving up.") break # Otherwise, wait and connect again. delay = minimum_backoff_time + random.randint(0, 1000) / 1000.0 - print('Waiting for {} before reconnecting.'.format(delay)) + print("Waiting for {} before reconnecting.".format(delay)) time.sleep(delay) minimum_backoff_time *= 2 client.connect(args.mqtt_bridge_hostname, args.mqtt_bridge_port) - payload = '{}/{}-payload-{}'.format( - args.registry_id, args.device_id, i) - print('Publishing message {}/{}: \'{}\''.format( - i, args.num_messages, payload)) + payload = "{}/{}-payload-{}".format(args.registry_id, args.device_id, i) + print("Publishing message {}/{}: '{}'".format(i, args.num_messages, payload)) # [START iot_mqtt_jwt_refresh] seconds_since_issue = (datetime.datetime.utcnow() - jwt_iat).seconds if seconds_since_issue > 60 * jwt_exp_mins: - print('Refreshing token after {}s'.format(seconds_since_issue)) + print("Refreshing token after {}s".format(seconds_since_issue)) jwt_iat = datetime.datetime.utcnow() client.loop() client.disconnect() client = get_client( - args.project_id, args.cloud_region, - args.registry_id, args.device_id, args.private_key_file, - args.algorithm, args.ca_certs, args.mqtt_bridge_hostname, - args.mqtt_bridge_port) + args.project_id, + args.cloud_region, + args.registry_id, + args.device_id, + args.private_key_file, + args.algorithm, + args.ca_certs, + args.mqtt_bridge_hostname, + args.mqtt_bridge_port, + ) # [END iot_mqtt_jwt_refresh] # Publish "payload" to the MQTT topic. qos=1 means at least once # delivery. Cloud IoT Core also supports qos=0 for at most once @@ -482,32 +572,51 @@ def mqtt_device_demo(args): def main(): args = parse_command_line_args() - if args.command.startswith('gateway'): - if (args.gateway_id is None): - print('Error: For gateway commands you must specify a gateway ID') + if args.command.startswith("gateway"): + if args.gateway_id is None: + print("Error: For gateway commands you must specify a gateway ID") return - if args.command == 'gateway_listen': + if args.command == "gateway_listen": listen_for_messages( - args.service_account_json, args.project_id, - args.cloud_region, args.registry_id, args.device_id, - args.gateway_id, args.num_messages, args.private_key_file, - args.algorithm, args.ca_certs, args.mqtt_bridge_hostname, - args.mqtt_bridge_port, args.jwt_expires_minutes, - args.listen_dur) + args.service_account_json, + args.project_id, + args.cloud_region, + args.registry_id, + args.device_id, + args.gateway_id, + args.num_messages, + args.private_key_file, + args.algorithm, + args.ca_certs, + args.mqtt_bridge_hostname, + args.mqtt_bridge_port, + args.jwt_expires_minutes, + args.listen_dur, + ) return - elif args.command == 'gateway_send': + elif args.command == "gateway_send": send_data_from_bound_device( - args.service_account_json, args.project_id, - args.cloud_region, args.registry_id, args.device_id, - args.gateway_id, args.num_messages, args.private_key_file, - args.algorithm, args.ca_certs, args.mqtt_bridge_hostname, - args.mqtt_bridge_port, args.jwt_expires_minutes, args.data) + args.service_account_json, + args.project_id, + args.cloud_region, + args.registry_id, + args.device_id, + args.gateway_id, + args.num_messages, + args.private_key_file, + args.algorithm, + args.ca_certs, + args.mqtt_bridge_hostname, + args.mqtt_bridge_port, + args.jwt_expires_minutes, + args.data, + ) return else: mqtt_device_demo(args) - print('Finished.') + print("Finished.") -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/samples/api-client/mqtt_example/noxfile.py b/samples/api-client/mqtt_example/noxfile.py new file mode 100644 index 00000000..3637109c --- /dev/null +++ b/samples/api-client/mqtt_example/noxfile.py @@ -0,0 +1,279 @@ +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import glob +import os +from pathlib import Path +import sys +from typing import Callable, Dict, List, Optional + +import nox + + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +BLACK_VERSION = "black==19.10b0" + +# Copy `noxfile_config.py` to your directory and modify it instead. + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + "ignored_versions": [], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "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': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "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": {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append(".") + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG["gcloud_project_env"] + # This should error out if not set. + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG["envs"]) + return ret + + +# DO NOT EDIT - automatically generated. +# 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"] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +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 +# + + +def _determine_local_import_names(start_dir: str) -> List[str]: + """Determines all import names that should be considered "local". + + This is used when running the linter to insure that import order is + properly checked. + """ + file_ext_pairs = [os.path.splitext(path) for path in os.listdir(start_dir)] + return [ + basename + for basename, extension in file_ext_pairs + if extension == ".py" + or os.path.isdir(os.path.join(start_dir, basename)) + and basename not in ("__pycache__") + ] + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--import-order-style=google", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG["enforce_type_hints"]: + session.install("flake8", "flake8-import-order") + else: + session.install("flake8", "flake8-import-order", "flake8-annotations") + + local_names = _determine_local_import_names(".") + args = FLAKE8_COMMON_ARGS + [ + "--application-import-names", + ",".join(local_names), + ".", + ] + session.run("flake8", *args) + + +# +# Black +# + + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + session.install(BLACK_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: + # check for presence of tests + test_list = glob.glob("*_test.py") + glob.glob("test_*.py") + test_list.extend(glob.glob("tests")) + if len(test_list) == 0: + print("No tests found, skipping directory.") + else: + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install( + "-r", "requirements-test.txt", "-c", "constraints-test.txt" + ) + else: + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # 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(), + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """ Returns the root folder of the project. """ + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/samples/api-client/mqtt_example/requirements-test.txt b/samples/api-client/mqtt_example/requirements-test.txt new file mode 100644 index 00000000..c2845bff --- /dev/null +++ b/samples/api-client/mqtt_example/requirements-test.txt @@ -0,0 +1 @@ +pytest==7.0.1 diff --git a/samples/api-client/mqtt_example/requirements.txt b/samples/api-client/mqtt_example/requirements.txt new file mode 100644 index 00000000..0779d49d --- /dev/null +++ b/samples/api-client/mqtt_example/requirements.txt @@ -0,0 +1,2 @@ +paho-mqtt==1.6.1 +pyjwt==2.3.0 diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_bind_device_to_gateway_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_bind_device_to_gateway_async.py new file mode 100644 index 00000000..1f237ae3 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_bind_device_to_gateway_async.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BindDeviceToGateway +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_BindDeviceToGateway_async] +from google.cloud import iot_v1 + + +async def sample_bind_device_to_gateway(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.BindDeviceToGatewayRequest( + parent="parent_value", + gateway_id="gateway_id_value", + device_id="device_id_value", + ) + + # Make the request + response = await client.bind_device_to_gateway(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_BindDeviceToGateway_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_bind_device_to_gateway_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_bind_device_to_gateway_sync.py new file mode 100644 index 00000000..13707ed7 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_bind_device_to_gateway_sync.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BindDeviceToGateway +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_BindDeviceToGateway_sync] +from google.cloud import iot_v1 + + +def sample_bind_device_to_gateway(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.BindDeviceToGatewayRequest( + parent="parent_value", + gateway_id="gateway_id_value", + device_id="device_id_value", + ) + + # Make the request + response = client.bind_device_to_gateway(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_BindDeviceToGateway_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_create_device_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_create_device_async.py new file mode 100644 index 00000000..7890a577 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_create_device_async.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateDevice +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_CreateDevice_async] +from google.cloud import iot_v1 + + +async def sample_create_device(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.CreateDeviceRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_device(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_CreateDevice_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_create_device_registry_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_create_device_registry_async.py new file mode 100644 index 00000000..804b0825 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_create_device_registry_async.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateDeviceRegistry +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_CreateDeviceRegistry_async] +from google.cloud import iot_v1 + + +async def sample_create_device_registry(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.CreateDeviceRegistryRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_device_registry(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_CreateDeviceRegistry_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_create_device_registry_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_create_device_registry_sync.py new file mode 100644 index 00000000..7f484f20 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_create_device_registry_sync.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateDeviceRegistry +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_CreateDeviceRegistry_sync] +from google.cloud import iot_v1 + + +def sample_create_device_registry(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.CreateDeviceRegistryRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_device_registry(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_CreateDeviceRegistry_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_create_device_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_create_device_sync.py new file mode 100644 index 00000000..3a945324 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_create_device_sync.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateDevice +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_CreateDevice_sync] +from google.cloud import iot_v1 + + +def sample_create_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.CreateDeviceRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_device(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_CreateDevice_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_delete_device_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_delete_device_async.py new file mode 100644 index 00000000..c4e76b81 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_delete_device_async.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteDevice +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_DeleteDevice_async] +from google.cloud import iot_v1 + + +async def sample_delete_device(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.DeleteDeviceRequest( + name="name_value", + ) + + # Make the request + await client.delete_device(request=request) + + +# [END cloudiot_generated_iot_v1_DeviceManager_DeleteDevice_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_delete_device_registry_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_delete_device_registry_async.py new file mode 100644 index 00000000..c52f86c6 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_delete_device_registry_async.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteDeviceRegistry +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_DeleteDeviceRegistry_async] +from google.cloud import iot_v1 + + +async def sample_delete_device_registry(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.DeleteDeviceRegistryRequest( + name="name_value", + ) + + # Make the request + await client.delete_device_registry(request=request) + + +# [END cloudiot_generated_iot_v1_DeviceManager_DeleteDeviceRegistry_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_delete_device_registry_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_delete_device_registry_sync.py new file mode 100644 index 00000000..02e678d5 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_delete_device_registry_sync.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteDeviceRegistry +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_DeleteDeviceRegistry_sync] +from google.cloud import iot_v1 + + +def sample_delete_device_registry(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.DeleteDeviceRegistryRequest( + name="name_value", + ) + + # Make the request + client.delete_device_registry(request=request) + + +# [END cloudiot_generated_iot_v1_DeviceManager_DeleteDeviceRegistry_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_delete_device_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_delete_device_sync.py new file mode 100644 index 00000000..81541b5d --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_delete_device_sync.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteDevice +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_DeleteDevice_sync] +from google.cloud import iot_v1 + + +def sample_delete_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.DeleteDeviceRequest( + name="name_value", + ) + + # Make the request + client.delete_device(request=request) + + +# [END cloudiot_generated_iot_v1_DeviceManager_DeleteDevice_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_device_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_device_async.py new file mode 100644 index 00000000..89c460d2 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_device_async.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetDevice +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_GetDevice_async] +from google.cloud import iot_v1 + + +async def sample_get_device(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.GetDeviceRequest( + name="name_value", + ) + + # Make the request + response = await client.get_device(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_GetDevice_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_device_registry_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_device_registry_async.py new file mode 100644 index 00000000..31efd0d7 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_device_registry_async.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetDeviceRegistry +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_GetDeviceRegistry_async] +from google.cloud import iot_v1 + + +async def sample_get_device_registry(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.GetDeviceRegistryRequest( + name="name_value", + ) + + # Make the request + response = await client.get_device_registry(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_GetDeviceRegistry_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_device_registry_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_device_registry_sync.py new file mode 100644 index 00000000..5943f5a1 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_device_registry_sync.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetDeviceRegistry +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_GetDeviceRegistry_sync] +from google.cloud import iot_v1 + + +def sample_get_device_registry(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.GetDeviceRegistryRequest( + name="name_value", + ) + + # Make the request + response = client.get_device_registry(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_GetDeviceRegistry_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_device_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_device_sync.py new file mode 100644 index 00000000..9107dbca --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_device_sync.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetDevice +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_GetDevice_sync] +from google.cloud import iot_v1 + + +def sample_get_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.GetDeviceRequest( + name="name_value", + ) + + # Make the request + response = client.get_device(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_GetDevice_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_iam_policy_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_iam_policy_async.py new file mode 100644 index 00000000..295a65fe --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_iam_policy_async.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetIamPolicy +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_GetIamPolicy_async] +from google.cloud import iot_v1 + + +async def sample_get_iam_policy(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.GetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = await client.get_iam_policy(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_GetIamPolicy_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_iam_policy_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_iam_policy_sync.py new file mode 100644 index 00000000..8910834f --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_get_iam_policy_sync.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetIamPolicy +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_GetIamPolicy_sync] +from google.cloud import iot_v1 + + +def sample_get_iam_policy(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.GetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = client.get_iam_policy(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_GetIamPolicy_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_config_versions_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_config_versions_async.py new file mode 100644 index 00000000..fbf32509 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_config_versions_async.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListDeviceConfigVersions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_ListDeviceConfigVersions_async] +from google.cloud import iot_v1 + + +async def sample_list_device_config_versions(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.ListDeviceConfigVersionsRequest( + name="name_value", + ) + + # Make the request + response = await client.list_device_config_versions(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_ListDeviceConfigVersions_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_config_versions_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_config_versions_sync.py new file mode 100644 index 00000000..4e01fd9d --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_config_versions_sync.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListDeviceConfigVersions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_ListDeviceConfigVersions_sync] +from google.cloud import iot_v1 + + +def sample_list_device_config_versions(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ListDeviceConfigVersionsRequest( + name="name_value", + ) + + # Make the request + response = client.list_device_config_versions(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_ListDeviceConfigVersions_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_registries_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_registries_async.py new file mode 100644 index 00000000..880c7c41 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_registries_async.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListDeviceRegistries +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_ListDeviceRegistries_async] +from google.cloud import iot_v1 + + +async def sample_list_device_registries(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.ListDeviceRegistriesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_device_registries(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_ListDeviceRegistries_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_registries_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_registries_sync.py new file mode 100644 index 00000000..2d5ef450 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_registries_sync.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListDeviceRegistries +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_ListDeviceRegistries_sync] +from google.cloud import iot_v1 + + +def sample_list_device_registries(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ListDeviceRegistriesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_device_registries(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_ListDeviceRegistries_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_states_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_states_async.py new file mode 100644 index 00000000..075f70ae --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_states_async.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListDeviceStates +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_ListDeviceStates_async] +from google.cloud import iot_v1 + + +async def sample_list_device_states(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.ListDeviceStatesRequest( + name="name_value", + ) + + # Make the request + response = await client.list_device_states(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_ListDeviceStates_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_states_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_states_sync.py new file mode 100644 index 00000000..681c83c2 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_device_states_sync.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListDeviceStates +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_ListDeviceStates_sync] +from google.cloud import iot_v1 + + +def sample_list_device_states(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ListDeviceStatesRequest( + name="name_value", + ) + + # Make the request + response = client.list_device_states(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_ListDeviceStates_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_devices_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_devices_async.py new file mode 100644 index 00000000..ac77f720 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_devices_async.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListDevices +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_ListDevices_async] +from google.cloud import iot_v1 + + +async def sample_list_devices(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.ListDevicesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_devices(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_ListDevices_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_devices_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_devices_sync.py new file mode 100644 index 00000000..ea51d220 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_list_devices_sync.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListDevices +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_ListDevices_sync] +from google.cloud import iot_v1 + + +def sample_list_devices(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ListDevicesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_devices(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_ListDevices_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_modify_cloud_to_device_config_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_modify_cloud_to_device_config_async.py new file mode 100644 index 00000000..4ee479cf --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_modify_cloud_to_device_config_async.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ModifyCloudToDeviceConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_ModifyCloudToDeviceConfig_async] +from google.cloud import iot_v1 + + +async def sample_modify_cloud_to_device_config(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.ModifyCloudToDeviceConfigRequest( + name="name_value", + binary_data=b'binary_data_blob', + ) + + # Make the request + response = await client.modify_cloud_to_device_config(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_ModifyCloudToDeviceConfig_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_modify_cloud_to_device_config_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_modify_cloud_to_device_config_sync.py new file mode 100644 index 00000000..5c048b90 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_modify_cloud_to_device_config_sync.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ModifyCloudToDeviceConfig +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_ModifyCloudToDeviceConfig_sync] +from google.cloud import iot_v1 + + +def sample_modify_cloud_to_device_config(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.ModifyCloudToDeviceConfigRequest( + name="name_value", + binary_data=b'binary_data_blob', + ) + + # Make the request + response = client.modify_cloud_to_device_config(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_ModifyCloudToDeviceConfig_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_send_command_to_device_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_send_command_to_device_async.py new file mode 100644 index 00000000..361d9575 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_send_command_to_device_async.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SendCommandToDevice +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_SendCommandToDevice_async] +from google.cloud import iot_v1 + + +async def sample_send_command_to_device(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.SendCommandToDeviceRequest( + name="name_value", + binary_data=b'binary_data_blob', + ) + + # Make the request + response = await client.send_command_to_device(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_SendCommandToDevice_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_send_command_to_device_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_send_command_to_device_sync.py new file mode 100644 index 00000000..f6c0bc78 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_send_command_to_device_sync.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SendCommandToDevice +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_SendCommandToDevice_sync] +from google.cloud import iot_v1 + + +def sample_send_command_to_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.SendCommandToDeviceRequest( + name="name_value", + binary_data=b'binary_data_blob', + ) + + # Make the request + response = client.send_command_to_device(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_SendCommandToDevice_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_set_iam_policy_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_set_iam_policy_async.py new file mode 100644 index 00000000..915c16d3 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_set_iam_policy_async.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SetIamPolicy +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_SetIamPolicy_async] +from google.cloud import iot_v1 + + +async def sample_set_iam_policy(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.SetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = await client.set_iam_policy(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_SetIamPolicy_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_set_iam_policy_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_set_iam_policy_sync.py new file mode 100644 index 00000000..70c8b526 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_set_iam_policy_sync.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SetIamPolicy +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_SetIamPolicy_sync] +from google.cloud import iot_v1 + + +def sample_set_iam_policy(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.SetIamPolicyRequest( + resource="resource_value", + ) + + # Make the request + response = client.set_iam_policy(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_SetIamPolicy_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_test_iam_permissions_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_test_iam_permissions_async.py new file mode 100644 index 00000000..7f577c30 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_test_iam_permissions_async.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for TestIamPermissions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_TestIamPermissions_async] +from google.cloud import iot_v1 + + +async def sample_test_iam_permissions(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.TestIamPermissionsRequest( + resource="resource_value", + permissions=['permissions_value_1', 'permissions_value_2'], + ) + + # Make the request + response = await client.test_iam_permissions(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_TestIamPermissions_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_test_iam_permissions_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_test_iam_permissions_sync.py new file mode 100644 index 00000000..da19dd05 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_test_iam_permissions_sync.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for TestIamPermissions +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_TestIamPermissions_sync] +from google.cloud import iot_v1 + + +def sample_test_iam_permissions(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.TestIamPermissionsRequest( + resource="resource_value", + permissions=['permissions_value_1', 'permissions_value_2'], + ) + + # Make the request + response = client.test_iam_permissions(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_TestIamPermissions_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_unbind_device_from_gateway_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_unbind_device_from_gateway_async.py new file mode 100644 index 00000000..d17aa3aa --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_unbind_device_from_gateway_async.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UnbindDeviceFromGateway +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_UnbindDeviceFromGateway_async] +from google.cloud import iot_v1 + + +async def sample_unbind_device_from_gateway(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.UnbindDeviceFromGatewayRequest( + parent="parent_value", + gateway_id="gateway_id_value", + device_id="device_id_value", + ) + + # Make the request + response = await client.unbind_device_from_gateway(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_UnbindDeviceFromGateway_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_unbind_device_from_gateway_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_unbind_device_from_gateway_sync.py new file mode 100644 index 00000000..402fd515 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_unbind_device_from_gateway_sync.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UnbindDeviceFromGateway +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_UnbindDeviceFromGateway_sync] +from google.cloud import iot_v1 + + +def sample_unbind_device_from_gateway(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.UnbindDeviceFromGatewayRequest( + parent="parent_value", + gateway_id="gateway_id_value", + device_id="device_id_value", + ) + + # Make the request + response = client.unbind_device_from_gateway(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_UnbindDeviceFromGateway_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_update_device_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_update_device_async.py new file mode 100644 index 00000000..25072957 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_update_device_async.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateDevice +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_UpdateDevice_async] +from google.cloud import iot_v1 + + +async def sample_update_device(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.UpdateDeviceRequest( + ) + + # Make the request + response = await client.update_device(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_UpdateDevice_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_update_device_registry_async.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_update_device_registry_async.py new file mode 100644 index 00000000..b69818ba --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_update_device_registry_async.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateDeviceRegistry +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_UpdateDeviceRegistry_async] +from google.cloud import iot_v1 + + +async def sample_update_device_registry(): + # Create a client + client = iot_v1.DeviceManagerAsyncClient() + + # Initialize request argument(s) + request = iot_v1.UpdateDeviceRegistryRequest( + ) + + # Make the request + response = await client.update_device_registry(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_UpdateDeviceRegistry_async] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_update_device_registry_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_update_device_registry_sync.py new file mode 100644 index 00000000..a3c571e6 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_update_device_registry_sync.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateDeviceRegistry +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_UpdateDeviceRegistry_sync] +from google.cloud import iot_v1 + + +def sample_update_device_registry(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.UpdateDeviceRegistryRequest( + ) + + # Make the request + response = client.update_device_registry(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_UpdateDeviceRegistry_sync] diff --git a/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_update_device_sync.py b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_update_device_sync.py new file mode 100644 index 00000000..735fe4e0 --- /dev/null +++ b/samples/generated_samples/cloudiot_generated_iot_v1_device_manager_update_device_sync.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateDevice +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-iot + + +# [START cloudiot_generated_iot_v1_DeviceManager_UpdateDevice_sync] +from google.cloud import iot_v1 + + +def sample_update_device(): + # Create a client + client = iot_v1.DeviceManagerClient() + + # Initialize request argument(s) + request = iot_v1.UpdateDeviceRequest( + ) + + # Make the request + response = client.update_device(request=request) + + # Handle the response + print(response) + +# [END cloudiot_generated_iot_v1_DeviceManager_UpdateDevice_sync] diff --git a/samples/generated_samples/snippet_metadata_iot_v1.json b/samples/generated_samples/snippet_metadata_iot_v1.json new file mode 100644 index 00000000..4579a13f --- /dev/null +++ b/samples/generated_samples/snippet_metadata_iot_v1.json @@ -0,0 +1,1687 @@ +{ + "snippets": [ + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "BindDeviceToGateway" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_bind_device_to_gateway_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_BindDeviceToGateway_async", + "segments": [ + { + "end": 46, + "start": 27, + "type": "FULL" + }, + { + "end": 46, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 40, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 43, + "start": 41, + "type": "REQUEST_EXECUTION" + }, + { + "end": 47, + "start": 44, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "BindDeviceToGateway" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_bind_device_to_gateway_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_BindDeviceToGateway_sync", + "segments": [ + { + "end": 46, + "start": 27, + "type": "FULL" + }, + { + "end": 46, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 40, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 43, + "start": 41, + "type": "REQUEST_EXECUTION" + }, + { + "end": 47, + "start": 44, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "CreateDeviceRegistry" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_create_device_registry_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_CreateDeviceRegistry_async", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "CreateDeviceRegistry" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_create_device_registry_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_CreateDeviceRegistry_sync", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "CreateDevice" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_create_device_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_CreateDevice_async", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "CreateDevice" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_create_device_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_CreateDevice_sync", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "DeleteDeviceRegistry" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_delete_device_registry_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_DeleteDeviceRegistry_async", + "segments": [ + { + "end": 42, + "start": 27, + "type": "FULL" + }, + { + "end": 42, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 43, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "DeleteDeviceRegistry" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_delete_device_registry_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_DeleteDeviceRegistry_sync", + "segments": [ + { + "end": 42, + "start": 27, + "type": "FULL" + }, + { + "end": 42, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 43, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "DeleteDevice" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_delete_device_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_DeleteDevice_async", + "segments": [ + { + "end": 42, + "start": 27, + "type": "FULL" + }, + { + "end": 42, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 43, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "DeleteDevice" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_delete_device_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_DeleteDevice_sync", + "segments": [ + { + "end": 42, + "start": 27, + "type": "FULL" + }, + { + "end": 42, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 43, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "GetDeviceRegistry" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_get_device_registry_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_GetDeviceRegistry_async", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "GetDeviceRegistry" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_get_device_registry_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_GetDeviceRegistry_sync", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "GetDevice" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_get_device_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_GetDevice_async", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "GetDevice" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_get_device_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_GetDevice_sync", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "GetIamPolicy" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_get_iam_policy_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_GetIamPolicy_async", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "GetIamPolicy" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_get_iam_policy_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_GetIamPolicy_sync", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "ListDeviceConfigVersions" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_list_device_config_versions_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_ListDeviceConfigVersions_async", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "ListDeviceConfigVersions" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_list_device_config_versions_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_ListDeviceConfigVersions_sync", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "ListDeviceRegistries" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_list_device_registries_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_ListDeviceRegistries_async", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "ListDeviceRegistries" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_list_device_registries_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_ListDeviceRegistries_sync", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "ListDeviceStates" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_list_device_states_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_ListDeviceStates_async", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "ListDeviceStates" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_list_device_states_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_ListDeviceStates_sync", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "ListDevices" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_list_devices_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_ListDevices_async", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "ListDevices" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_list_devices_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_ListDevices_sync", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "ModifyCloudToDeviceConfig" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_modify_cloud_to_device_config_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_ModifyCloudToDeviceConfig_async", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 39, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 42, + "start": 40, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 43, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "ModifyCloudToDeviceConfig" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_modify_cloud_to_device_config_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_ModifyCloudToDeviceConfig_sync", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 39, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 42, + "start": 40, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 43, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "SendCommandToDevice" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_send_command_to_device_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_SendCommandToDevice_async", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 39, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 42, + "start": 40, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 43, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "SendCommandToDevice" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_send_command_to_device_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_SendCommandToDevice_sync", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 39, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 42, + "start": 40, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 43, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "SetIamPolicy" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_set_iam_policy_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_SetIamPolicy_async", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "SetIamPolicy" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_set_iam_policy_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_SetIamPolicy_sync", + "segments": [ + { + "end": 44, + "start": 27, + "type": "FULL" + }, + { + "end": 44, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 38, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 41, + "start": 39, + "type": "REQUEST_EXECUTION" + }, + { + "end": 45, + "start": 42, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "TestIamPermissions" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_test_iam_permissions_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_TestIamPermissions_async", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 39, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 42, + "start": 40, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 43, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "TestIamPermissions" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_test_iam_permissions_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_TestIamPermissions_sync", + "segments": [ + { + "end": 45, + "start": 27, + "type": "FULL" + }, + { + "end": 45, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 39, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 42, + "start": 40, + "type": "REQUEST_EXECUTION" + }, + { + "end": 46, + "start": 43, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "UnbindDeviceFromGateway" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_unbind_device_from_gateway_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_UnbindDeviceFromGateway_async", + "segments": [ + { + "end": 46, + "start": 27, + "type": "FULL" + }, + { + "end": 46, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 40, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 43, + "start": 41, + "type": "REQUEST_EXECUTION" + }, + { + "end": 47, + "start": 44, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "UnbindDeviceFromGateway" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_unbind_device_from_gateway_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_UnbindDeviceFromGateway_sync", + "segments": [ + { + "end": 46, + "start": 27, + "type": "FULL" + }, + { + "end": 46, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 40, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 43, + "start": 41, + "type": "REQUEST_EXECUTION" + }, + { + "end": 47, + "start": 44, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "UpdateDeviceRegistry" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_update_device_registry_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_UpdateDeviceRegistry_async", + "segments": [ + { + "end": 43, + "start": 27, + "type": "FULL" + }, + { + "end": 43, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 37, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 40, + "start": 38, + "type": "REQUEST_EXECUTION" + }, + { + "end": 44, + "start": 41, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "UpdateDeviceRegistry" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_update_device_registry_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_UpdateDeviceRegistry_sync", + "segments": [ + { + "end": 43, + "start": 27, + "type": "FULL" + }, + { + "end": 43, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 37, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 40, + "start": 38, + "type": "REQUEST_EXECUTION" + }, + { + "end": 44, + "start": 41, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "async": true, + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "UpdateDevice" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_update_device_async.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_UpdateDevice_async", + "segments": [ + { + "end": 43, + "start": 27, + "type": "FULL" + }, + { + "end": 43, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 37, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 40, + "start": 38, + "type": "REQUEST_EXECUTION" + }, + { + "end": 44, + "start": 41, + "type": "RESPONSE_HANDLING" + } + ] + }, + { + "clientMethod": { + "method": { + "service": { + "shortName": "DeviceManager" + }, + "shortName": "UpdateDevice" + } + }, + "file": "cloudiot_generated_iot_v1_device_manager_update_device_sync.py", + "regionTag": "cloudiot_generated_iot_v1_DeviceManager_UpdateDevice_sync", + "segments": [ + { + "end": 43, + "start": 27, + "type": "FULL" + }, + { + "end": 43, + "start": 27, + "type": "SHORT" + }, + { + "end": 33, + "start": 31, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 37, + "start": 34, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 40, + "start": 38, + "type": "REQUEST_EXECUTION" + }, + { + "end": 44, + "start": 41, + "type": "RESPONSE_HANDLING" + } + ] + } + ] +} diff --git a/scripts/readme-gen/templates/README.tmpl.rst b/scripts/readme-gen/templates/README.tmpl.rst index 4fd23976..faa6071c 100644 --- a/scripts/readme-gen/templates/README.tmpl.rst +++ b/scripts/readme-gen/templates/README.tmpl.rst @@ -6,7 +6,7 @@ =============================================================================== .. image:: https://gstatic.com/cloudssh/images/open-btn.png - :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor={{folder}}/README.rst + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/python-iot&page=editor&open_in_editor={{folder}}/README.rst This directory contains samples for {{product.name}}. {{product.description}} @@ -46,7 +46,7 @@ Samples {% if not sample.hide_cloudshell_button %} .. image:: https://gstatic.com/cloudssh/images/open-btn.png - :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor={{folder}}/{{sample.file}},{{folder}}/README.rst + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/python-iot&page=editor&open_in_editor={{folder}}/{{sample.file}},{{folder}}/README.rst {% endif %} diff --git a/scripts/readme-gen/templates/install_deps.tmpl.rst b/scripts/readme-gen/templates/install_deps.tmpl.rst index 275d6498..ca60ac23 100644 --- a/scripts/readme-gen/templates/install_deps.tmpl.rst +++ b/scripts/readme-gen/templates/install_deps.tmpl.rst @@ -1,11 +1,11 @@ Install Dependencies ++++++++++++++++++++ -#. Clone python-docs-samples and change directory to the sample directory you want to use. +#. Clone python-iot and change directory to the sample directory you want to use. .. code-block:: bash - $ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git + $ git clone https://github.com/googleapis/python-iot.git #. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions. diff --git a/setup.py b/setup.py index ea658b0b..6217458e 100644 --- a/setup.py +++ b/setup.py @@ -19,16 +19,15 @@ name = "google-cloud-iot" description = "Cloud IoT API API client library" -version = "2.3.0" +version = "2.4.0" release_status = "Development Status :: 5 - Production/Stable" dependencies = [ # 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-api-core[grpc] >= 1.26.0, <3.0.0dev", + "google-api-core[grpc] >= 1.28.0, <3.0.0dev", "grpc-google-iam-v1 >= 0.12.3, < 0.13dev", - "proto-plus >= 1.4.0", - "packaging >= 14.3", + "proto-plus >= 1.15.0", ] extras = {"libcst": "libcst >= 0.2.5"} @@ -67,6 +66,8 @@ "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", "Operating System :: OS Independent", "Topic :: Internet", ], @@ -74,7 +75,7 @@ packages=packages, namespace_packages=namespaces, install_requires=dependencies, - extras_requires=extras, + extras_require=extras, python_requires=">=3.6", scripts=["scripts/fixup_iot_v1_keywords.py"], include_package_data=True, diff --git a/testing/constraints-3.6.txt b/testing/constraints-3.6.txt index a07c242f..685bbab0 100644 --- a/testing/constraints-3.6.txt +++ b/testing/constraints-3.6.txt @@ -4,9 +4,6 @@ # Pin the version to the lower bound. # e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0dev", # Then this file should have google-cloud-foo==1.14.0 -google-api-core==1.26.0 -proto-plus==1.4.0 +google-api-core==1.28.0 +proto-plus==1.15.0 grpc-google-iam-v1==0.12.3 -libcst==0.2.5 -packaging==14.3 -google-auth==1.24.0 # TODO: remove when google-auth>=1.25.0 si transitively required through google-api-core diff --git a/tests/unit/gapic/iot_v1/test_device_manager.py b/tests/unit/gapic/iot_v1/test_device_manager.py index f6bde2a7..ace8c5aa 100644 --- a/tests/unit/gapic/iot_v1/test_device_manager.py +++ b/tests/unit/gapic/iot_v1/test_device_manager.py @@ -15,7 +15,6 @@ # import os import mock -import packaging.version import grpc from grpc.experimental import aio @@ -29,15 +28,13 @@ 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.iot_v1.services.device_manager import DeviceManagerAsyncClient from google.cloud.iot_v1.services.device_manager import DeviceManagerClient from google.cloud.iot_v1.services.device_manager import pagers from google.cloud.iot_v1.services.device_manager import transports -from google.cloud.iot_v1.services.device_manager.transports.base import ( - _GOOGLE_AUTH_VERSION, -) from google.cloud.iot_v1.types import device_manager from google.cloud.iot_v1.types import resources from google.iam.v1 import iam_policy_pb2 # type: ignore @@ -52,20 +49,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_device_manager_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_device_manager_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_device_manager_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, @@ -272,20 +255,20 @@ def test_device_manager_client_client_options( # unsupported value. with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): with pytest.raises(MutualTLSChannelError): - client = client_class() + client = client_class(transport=transport_name) # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. with mock.patch.dict( os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} ): with pytest.raises(ValueError): - client = client_class() + client = client_class(transport=transport_name) # Check the case quota_project_id is provided options = client_options.ClientOptions(quota_project_id="octopus") with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(client_options=options) + client = client_class(client_options=options, transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -344,7 +327,7 @@ def test_device_manager_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(client_options=options, transport=transport_name) if use_client_cert_env == "false": expected_client_cert_source = None @@ -386,7 +369,7 @@ def test_device_manager_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, @@ -408,7 +391,7 @@ def test_device_manager_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, @@ -421,6 +404,87 @@ def test_device_manager_client_mtls_env_auto( ) +@pytest.mark.parametrize( + "client_class", [DeviceManagerClient, DeviceManagerAsyncClient] +) +@mock.patch.object( + DeviceManagerClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(DeviceManagerClient), +) +@mock.patch.object( + DeviceManagerAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(DeviceManagerAsyncClient), +) +def test_device_manager_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + @pytest.mark.parametrize( "client_class,transport_class,transport_name", [ @@ -439,7 +503,7 @@ def test_device_manager_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(client_options=options, transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file=None, @@ -453,24 +517,31 @@ def test_device_manager_client_client_options_scopes( @pytest.mark.parametrize( - "client_class,transport_class,transport_name", + "client_class,transport_class,transport_name,grpc_helpers", [ - (DeviceManagerClient, transports.DeviceManagerGrpcTransport, "grpc"), + ( + DeviceManagerClient, + transports.DeviceManagerGrpcTransport, + "grpc", + grpc_helpers, + ), ( DeviceManagerAsyncClient, transports.DeviceManagerGrpcAsyncIOTransport, "grpc_asyncio", + grpc_helpers_async, ), ], ) def test_device_manager_client_client_options_credentials_file( - client_class, transport_class, transport_name + client_class, transport_class, transport_name, grpc_helpers ): # Check the case credentials file is provided. options = client_options.ClientOptions(credentials_file="credentials.json") + with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None - client = client_class(client_options=options) + client = client_class(client_options=options, transport=transport_name) patched.assert_called_once_with( credentials=None, credentials_file="credentials.json", @@ -503,9 +574,79 @@ def test_device_manager_client_client_options_from_dict(): ) -def test_create_device_registry( - transport: str = "grpc", request_type=device_manager.CreateDeviceRegistryRequest +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + DeviceManagerClient, + transports.DeviceManagerGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + DeviceManagerAsyncClient, + transports.DeviceManagerGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_device_manager_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers ): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "cloudiot.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloudiot", + ), + scopes=None, + default_host="cloudiot.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", [device_manager.CreateDeviceRegistryRequest, dict,] +) +def test_create_device_registry(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -536,10 +677,6 @@ def test_create_device_registry( assert response.log_level == resources.LogLevel.NONE -def test_create_device_registry_from_dict(): - test_create_device_registry(request_type=dict) - - def test_create_device_registry_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -676,8 +813,12 @@ def test_create_device_registry_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].device_registry == resources.DeviceRegistry(id="id_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].device_registry + mock_val = resources.DeviceRegistry(id="id_value") + assert arg == mock_val def test_create_device_registry_flattened_error(): @@ -720,8 +861,12 @@ async def test_create_device_registry_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].device_registry == resources.DeviceRegistry(id="id_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].device_registry + mock_val = resources.DeviceRegistry(id="id_value") + assert arg == mock_val @pytest.mark.asyncio @@ -740,9 +885,10 @@ async def test_create_device_registry_flattened_error_async(): ) -def test_get_device_registry( - transport: str = "grpc", request_type=device_manager.GetDeviceRegistryRequest -): +@pytest.mark.parametrize( + "request_type", [device_manager.GetDeviceRegistryRequest, dict,] +) +def test_get_device_registry(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -773,10 +919,6 @@ def test_get_device_registry( assert response.log_level == resources.LogLevel.NONE -def test_get_device_registry_from_dict(): - test_get_device_registry(request_type=dict) - - def test_get_device_registry_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -910,7 +1052,9 @@ def test_get_device_registry_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_device_registry_flattened_error(): @@ -948,7 +1092,9 @@ async def test_get_device_registry_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -965,9 +1111,10 @@ async def test_get_device_registry_flattened_error_async(): ) -def test_update_device_registry( - transport: str = "grpc", request_type=device_manager.UpdateDeviceRegistryRequest -): +@pytest.mark.parametrize( + "request_type", [device_manager.UpdateDeviceRegistryRequest, dict,] +) +def test_update_device_registry(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -998,10 +1145,6 @@ def test_update_device_registry( assert response.log_level == resources.LogLevel.NONE -def test_update_device_registry_from_dict(): - test_update_device_registry(request_type=dict) - - def test_update_device_registry_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -1144,8 +1287,12 @@ def test_update_device_registry_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].device_registry == resources.DeviceRegistry(id="id_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].device_registry + mock_val = resources.DeviceRegistry(id="id_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val def test_update_device_registry_flattened_error(): @@ -1188,8 +1335,12 @@ async def test_update_device_registry_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].device_registry == resources.DeviceRegistry(id="id_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].device_registry + mock_val = resources.DeviceRegistry(id="id_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val @pytest.mark.asyncio @@ -1208,9 +1359,10 @@ async def test_update_device_registry_flattened_error_async(): ) -def test_delete_device_registry( - transport: str = "grpc", request_type=device_manager.DeleteDeviceRegistryRequest -): +@pytest.mark.parametrize( + "request_type", [device_manager.DeleteDeviceRegistryRequest, dict,] +) +def test_delete_device_registry(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -1236,10 +1388,6 @@ def test_delete_device_registry( assert response is None -def test_delete_device_registry_from_dict(): - test_delete_device_registry(request_type=dict) - - def test_delete_device_registry_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -1364,7 +1512,9 @@ def test_delete_device_registry_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_device_registry_flattened_error(): @@ -1400,7 +1550,9 @@ async def test_delete_device_registry_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1417,9 +1569,10 @@ async def test_delete_device_registry_flattened_error_async(): ) -def test_list_device_registries( - transport: str = "grpc", request_type=device_manager.ListDeviceRegistriesRequest -): +@pytest.mark.parametrize( + "request_type", [device_manager.ListDeviceRegistriesRequest, dict,] +) +def test_list_device_registries(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -1448,10 +1601,6 @@ def test_list_device_registries( assert response.next_page_token == "next_page_token_value" -def test_list_device_registries_from_dict(): - test_list_device_registries(request_type=dict) - - def test_list_device_registries_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -1583,7 +1732,9 @@ def test_list_device_registries_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_device_registries_flattened_error(): @@ -1621,7 +1772,9 @@ async def test_list_device_registries_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -1638,8 +1791,10 @@ async def test_list_device_registries_flattened_error_async(): ) -def test_list_device_registries_pager(): - client = DeviceManagerClient(credentials=ga_credentials.AnonymousCredentials,) +def test_list_device_registries_pager(transport_name: str = "grpc"): + client = DeviceManagerClient( + credentials=ga_credentials.AnonymousCredentials, transport=transport_name, + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -1683,8 +1838,10 @@ def test_list_device_registries_pager(): assert all(isinstance(i, resources.DeviceRegistry) for i in results) -def test_list_device_registries_pages(): - client = DeviceManagerClient(credentials=ga_credentials.AnonymousCredentials,) +def test_list_device_registries_pages(transport_name: str = "grpc"): + client = DeviceManagerClient( + credentials=ga_credentials.AnonymousCredentials, transport=transport_name, + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -1804,9 +1961,8 @@ async def test_list_device_registries_async_pages(): assert page_.raw_page.next_page_token == token -def test_create_device( - transport: str = "grpc", request_type=device_manager.CreateDeviceRequest -): +@pytest.mark.parametrize("request_type", [device_manager.CreateDeviceRequest, dict,]) +def test_create_device(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -1841,10 +1997,6 @@ def test_create_device( assert response.log_level == resources.LogLevel.NONE -def test_create_device_from_dict(): - test_create_device(request_type=dict) - - def test_create_device_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -1973,8 +2125,12 @@ def test_create_device_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].device == resources.Device(id="id_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].device + mock_val = resources.Device(id="id_value") + assert arg == mock_val def test_create_device_flattened_error(): @@ -2012,8 +2168,12 @@ async def test_create_device_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].device == resources.Device(id="id_value") + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].device + mock_val = resources.Device(id="id_value") + assert arg == mock_val @pytest.mark.asyncio @@ -2032,9 +2192,8 @@ async def test_create_device_flattened_error_async(): ) -def test_get_device( - transport: str = "grpc", request_type=device_manager.GetDeviceRequest -): +@pytest.mark.parametrize("request_type", [device_manager.GetDeviceRequest, dict,]) +def test_get_device(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -2069,10 +2228,6 @@ def test_get_device( assert response.log_level == resources.LogLevel.NONE -def test_get_device_from_dict(): - test_get_device(request_type=dict) - - def test_get_device_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -2199,7 +2354,9 @@ def test_get_device_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_get_device_flattened_error(): @@ -2233,7 +2390,9 @@ async def test_get_device_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2250,9 +2409,8 @@ async def test_get_device_flattened_error_async(): ) -def test_update_device( - transport: str = "grpc", request_type=device_manager.UpdateDeviceRequest -): +@pytest.mark.parametrize("request_type", [device_manager.UpdateDeviceRequest, dict,]) +def test_update_device(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -2287,10 +2445,6 @@ def test_update_device( assert response.log_level == resources.LogLevel.NONE -def test_update_device_from_dict(): - test_update_device(request_type=dict) - - def test_update_device_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -2420,8 +2574,12 @@ def test_update_device_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].device == resources.Device(id="id_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].device + mock_val = resources.Device(id="id_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val def test_update_device_flattened_error(): @@ -2460,8 +2618,12 @@ async def test_update_device_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].device == resources.Device(id="id_value") - assert args[0].update_mask == field_mask_pb2.FieldMask(paths=["paths_value"]) + arg = args[0].device + mock_val = resources.Device(id="id_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val @pytest.mark.asyncio @@ -2480,9 +2642,8 @@ async def test_update_device_flattened_error_async(): ) -def test_delete_device( - transport: str = "grpc", request_type=device_manager.DeleteDeviceRequest -): +@pytest.mark.parametrize("request_type", [device_manager.DeleteDeviceRequest, dict,]) +def test_delete_device(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -2506,10 +2667,6 @@ def test_delete_device( assert response is None -def test_delete_device_from_dict(): - test_delete_device(request_type=dict) - - def test_delete_device_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -2623,7 +2780,9 @@ def test_delete_device_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_delete_device_flattened_error(): @@ -2657,7 +2816,9 @@ async def test_delete_device_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2674,9 +2835,8 @@ async def test_delete_device_flattened_error_async(): ) -def test_list_devices( - transport: str = "grpc", request_type=device_manager.ListDevicesRequest -): +@pytest.mark.parametrize("request_type", [device_manager.ListDevicesRequest, dict,]) +def test_list_devices(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -2703,10 +2863,6 @@ def test_list_devices( assert response.next_page_token == "next_page_token_value" -def test_list_devices_from_dict(): - test_list_devices(request_type=dict) - - def test_list_devices_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -2825,7 +2981,9 @@ def test_list_devices_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val def test_list_devices_flattened_error(): @@ -2861,7 +3019,9 @@ async def test_list_devices_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val @pytest.mark.asyncio @@ -2878,8 +3038,10 @@ async def test_list_devices_flattened_error_async(): ) -def test_list_devices_pager(): - client = DeviceManagerClient(credentials=ga_credentials.AnonymousCredentials,) +def test_list_devices_pager(transport_name: str = "grpc"): + client = DeviceManagerClient( + credentials=ga_credentials.AnonymousCredentials, transport=transport_name, + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.list_devices), "__call__") as call: @@ -2912,8 +3074,10 @@ def test_list_devices_pager(): assert all(isinstance(i, resources.Device) for i in results) -def test_list_devices_pages(): - client = DeviceManagerClient(credentials=ga_credentials.AnonymousCredentials,) +def test_list_devices_pages(transport_name: str = "grpc"): + client = DeviceManagerClient( + credentials=ga_credentials.AnonymousCredentials, transport=transport_name, + ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.list_devices), "__call__") as call: @@ -3000,10 +3164,10 @@ async def test_list_devices_async_pages(): assert page_.raw_page.next_page_token == token -def test_modify_cloud_to_device_config( - transport: str = "grpc", - request_type=device_manager.ModifyCloudToDeviceConfigRequest, -): +@pytest.mark.parametrize( + "request_type", [device_manager.ModifyCloudToDeviceConfigRequest, dict,] +) +def test_modify_cloud_to_device_config(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -3033,10 +3197,6 @@ def test_modify_cloud_to_device_config( assert response.binary_data == b"binary_data_blob" -def test_modify_cloud_to_device_config_from_dict(): - test_modify_cloud_to_device_config(request_type=dict) - - def test_modify_cloud_to_device_config_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -3169,8 +3329,12 @@ def test_modify_cloud_to_device_config_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].binary_data == b"binary_data_blob" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].binary_data + mock_val = b"binary_data_blob" + assert arg == mock_val def test_modify_cloud_to_device_config_flattened_error(): @@ -3212,8 +3376,12 @@ async def test_modify_cloud_to_device_config_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].binary_data == b"binary_data_blob" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].binary_data + mock_val = b"binary_data_blob" + assert arg == mock_val @pytest.mark.asyncio @@ -3232,9 +3400,10 @@ async def test_modify_cloud_to_device_config_flattened_error_async(): ) -def test_list_device_config_versions( - transport: str = "grpc", request_type=device_manager.ListDeviceConfigVersionsRequest -): +@pytest.mark.parametrize( + "request_type", [device_manager.ListDeviceConfigVersionsRequest, dict,] +) +def test_list_device_config_versions(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -3260,10 +3429,6 @@ def test_list_device_config_versions( assert isinstance(response, device_manager.ListDeviceConfigVersionsResponse) -def test_list_device_config_versions_from_dict(): - test_list_device_config_versions(request_type=dict) - - def test_list_device_config_versions_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -3392,7 +3557,9 @@ def test_list_device_config_versions_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_list_device_config_versions_flattened_error(): @@ -3430,7 +3597,9 @@ async def test_list_device_config_versions_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3447,9 +3616,10 @@ async def test_list_device_config_versions_flattened_error_async(): ) -def test_list_device_states( - transport: str = "grpc", request_type=device_manager.ListDeviceStatesRequest -): +@pytest.mark.parametrize( + "request_type", [device_manager.ListDeviceStatesRequest, dict,] +) +def test_list_device_states(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -3475,10 +3645,6 @@ def test_list_device_states( assert isinstance(response, device_manager.ListDeviceStatesResponse) -def test_list_device_states_from_dict(): - test_list_device_states(request_type=dict) - - def test_list_device_states_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -3606,7 +3772,9 @@ def test_list_device_states_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val def test_list_device_states_flattened_error(): @@ -3644,7 +3812,9 @@ async def test_list_device_states_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3661,9 +3831,8 @@ async def test_list_device_states_flattened_error_async(): ) -def test_set_iam_policy( - transport: str = "grpc", request_type=iam_policy_pb2.SetIamPolicyRequest -): +@pytest.mark.parametrize("request_type", [iam_policy_pb2.SetIamPolicyRequest, dict,]) +def test_set_iam_policy(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -3689,10 +3858,6 @@ def test_set_iam_policy( assert response.etag == b"etag_blob" -def test_set_iam_policy_from_dict(): - test_set_iam_policy(request_type=dict) - - def test_set_iam_policy_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -3825,7 +3990,9 @@ def test_set_iam_policy_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].resource == "resource_value" + arg = args[0].resource + mock_val = "resource_value" + assert arg == mock_val def test_set_iam_policy_flattened_error(): @@ -3859,7 +4026,9 @@ async def test_set_iam_policy_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].resource == "resource_value" + arg = args[0].resource + mock_val = "resource_value" + assert arg == mock_val @pytest.mark.asyncio @@ -3876,9 +4045,8 @@ async def test_set_iam_policy_flattened_error_async(): ) -def test_get_iam_policy( - transport: str = "grpc", request_type=iam_policy_pb2.GetIamPolicyRequest -): +@pytest.mark.parametrize("request_type", [iam_policy_pb2.GetIamPolicyRequest, dict,]) +def test_get_iam_policy(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -3904,10 +4072,6 @@ def test_get_iam_policy( assert response.etag == b"etag_blob" -def test_get_iam_policy_from_dict(): - test_get_iam_policy(request_type=dict) - - def test_get_iam_policy_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -4040,7 +4204,9 @@ def test_get_iam_policy_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].resource == "resource_value" + arg = args[0].resource + mock_val = "resource_value" + assert arg == mock_val def test_get_iam_policy_flattened_error(): @@ -4074,7 +4240,9 @@ async def test_get_iam_policy_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].resource == "resource_value" + arg = args[0].resource + mock_val = "resource_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4091,9 +4259,10 @@ async def test_get_iam_policy_flattened_error_async(): ) -def test_test_iam_permissions( - transport: str = "grpc", request_type=iam_policy_pb2.TestIamPermissionsRequest -): +@pytest.mark.parametrize( + "request_type", [iam_policy_pb2.TestIamPermissionsRequest, dict,] +) +def test_test_iam_permissions(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -4122,10 +4291,6 @@ def test_test_iam_permissions( assert response.permissions == ["permissions_value"] -def test_test_iam_permissions_from_dict(): - test_test_iam_permissions(request_type=dict) - - def test_test_iam_permissions_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -4276,8 +4441,12 @@ def test_test_iam_permissions_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].resource == "resource_value" - assert args[0].permissions == ["permissions_value"] + arg = args[0].resource + mock_val = "resource_value" + assert arg == mock_val + arg = args[0].permissions + mock_val = ["permissions_value"] + assert arg == mock_val def test_test_iam_permissions_flattened_error(): @@ -4319,8 +4488,12 @@ async def test_test_iam_permissions_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].resource == "resource_value" - assert args[0].permissions == ["permissions_value"] + arg = args[0].resource + mock_val = "resource_value" + assert arg == mock_val + arg = args[0].permissions + mock_val = ["permissions_value"] + assert arg == mock_val @pytest.mark.asyncio @@ -4339,9 +4512,10 @@ async def test_test_iam_permissions_flattened_error_async(): ) -def test_send_command_to_device( - transport: str = "grpc", request_type=device_manager.SendCommandToDeviceRequest -): +@pytest.mark.parametrize( + "request_type", [device_manager.SendCommandToDeviceRequest, dict,] +) +def test_send_command_to_device(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -4367,10 +4541,6 @@ def test_send_command_to_device( assert isinstance(response, device_manager.SendCommandToDeviceResponse) -def test_send_command_to_device_from_dict(): - test_send_command_to_device(request_type=dict) - - def test_send_command_to_device_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -4503,9 +4673,15 @@ def test_send_command_to_device_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].binary_data == b"binary_data_blob" - assert args[0].subfolder == "subfolder_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].binary_data + mock_val = b"binary_data_blob" + assert arg == mock_val + arg = args[0].subfolder + mock_val = "subfolder_value" + assert arg == mock_val def test_send_command_to_device_flattened_error(): @@ -4550,9 +4726,15 @@ async def test_send_command_to_device_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].binary_data == b"binary_data_blob" - assert args[0].subfolder == "subfolder_value" + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + arg = args[0].binary_data + mock_val = b"binary_data_blob" + assert arg == mock_val + arg = args[0].subfolder + mock_val = "subfolder_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4572,9 +4754,10 @@ async def test_send_command_to_device_flattened_error_async(): ) -def test_bind_device_to_gateway( - transport: str = "grpc", request_type=device_manager.BindDeviceToGatewayRequest -): +@pytest.mark.parametrize( + "request_type", [device_manager.BindDeviceToGatewayRequest, dict,] +) +def test_bind_device_to_gateway(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -4600,10 +4783,6 @@ def test_bind_device_to_gateway( assert isinstance(response, device_manager.BindDeviceToGatewayResponse) -def test_bind_device_to_gateway_from_dict(): - test_bind_device_to_gateway(request_type=dict) - - def test_bind_device_to_gateway_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -4736,9 +4915,15 @@ def test_bind_device_to_gateway_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].gateway_id == "gateway_id_value" - assert args[0].device_id == "device_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].gateway_id + mock_val = "gateway_id_value" + assert arg == mock_val + arg = args[0].device_id + mock_val = "device_id_value" + assert arg == mock_val def test_bind_device_to_gateway_flattened_error(): @@ -4783,9 +4968,15 @@ async def test_bind_device_to_gateway_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].gateway_id == "gateway_id_value" - assert args[0].device_id == "device_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].gateway_id + mock_val = "gateway_id_value" + assert arg == mock_val + arg = args[0].device_id + mock_val = "device_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -4805,9 +4996,10 @@ async def test_bind_device_to_gateway_flattened_error_async(): ) -def test_unbind_device_from_gateway( - transport: str = "grpc", request_type=device_manager.UnbindDeviceFromGatewayRequest -): +@pytest.mark.parametrize( + "request_type", [device_manager.UnbindDeviceFromGatewayRequest, dict,] +) +def test_unbind_device_from_gateway(request_type, transport: str = "grpc"): client = DeviceManagerClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) @@ -4833,10 +5025,6 @@ def test_unbind_device_from_gateway( assert isinstance(response, device_manager.UnbindDeviceFromGatewayResponse) -def test_unbind_device_from_gateway_from_dict(): - test_unbind_device_from_gateway(request_type=dict) - - def test_unbind_device_from_gateway_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. @@ -4969,9 +5157,15 @@ def test_unbind_device_from_gateway_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].gateway_id == "gateway_id_value" - assert args[0].device_id == "device_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].gateway_id + mock_val = "gateway_id_value" + assert arg == mock_val + arg = args[0].device_id + mock_val = "device_id_value" + assert arg == mock_val def test_unbind_device_from_gateway_flattened_error(): @@ -5016,9 +5210,15 @@ async def test_unbind_device_from_gateway_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].gateway_id == "gateway_id_value" - assert args[0].device_id == "device_id_value" + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].gateway_id + mock_val = "gateway_id_value" + assert arg == mock_val + arg = args[0].device_id + mock_val = "device_id_value" + assert arg == mock_val @pytest.mark.asyncio @@ -5058,6 +5258,23 @@ def test_credentials_transport_error(): transport=transport, ) + # It is an error to provide an api_key and a transport instance. + transport = transports.DeviceManagerGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DeviceManagerClient(client_options=options, transport=transport,) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DeviceManagerClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + # It is an error to provide scopes and a transport instance. transport = transports.DeviceManagerGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), @@ -5159,8 +5376,10 @@ def test_device_manager_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_device_manager_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( @@ -5184,29 +5403,6 @@ def test_device_manager_base_transport_with_credentials_file(): ) -@requires_google_auth_lt_1_25_0 -def test_device_manager_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.iot_v1.services.device_manager.transports.DeviceManagerTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.DeviceManagerTransport( - 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/cloudiot", - ), - quota_project_id="octopus", - ) - - def test_device_manager_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( @@ -5218,7 +5414,6 @@ def test_device_manager_base_transport_with_adc(): adc.assert_called_once() -@requires_google_auth_gte_1_25_0 def test_device_manager_auth_adc(): # If no credentials are provided, we should use ADC credentials. with mock.patch.object(google.auth, "default", autospec=True) as adc: @@ -5234,21 +5429,6 @@ def test_device_manager_auth_adc(): ) -@requires_google_auth_lt_1_25_0 -def test_device_manager_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) - DeviceManagerClient() - adc.assert_called_once_with( - scopes=( - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloudiot", - ), - quota_project_id=None, - ) - - @pytest.mark.parametrize( "transport_class", [ @@ -5256,7 +5436,6 @@ def test_device_manager_auth_adc_old_google_auth(): transports.DeviceManagerGrpcAsyncIOTransport, ], ) -@requires_google_auth_gte_1_25_0 def test_device_manager_transport_auth_adc(transport_class): # If credentials and host are not provided, the transport class should use # ADC credentials. @@ -5273,29 +5452,6 @@ def test_device_manager_transport_auth_adc(transport_class): ) -@pytest.mark.parametrize( - "transport_class", - [ - transports.DeviceManagerGrpcTransport, - transports.DeviceManagerGrpcAsyncIOTransport, - ], -) -@requires_google_auth_lt_1_25_0 -def test_device_manager_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/cloudiot", - ), - quota_project_id="octopus", - ) - - @pytest.mark.parametrize( "transport_class,grpc_helpers", [ @@ -5667,7 +5823,7 @@ def test_parse_common_location_path(): assert expected == actual -def test_client_withDEFAULT_CLIENT_INFO(): +def test_client_with_default_client_info(): client_info = gapic_v1.client_info.ClientInfo() with mock.patch.object( @@ -5686,3 +5842,79 @@ 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 = DeviceManagerAsyncClient( + 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 = DeviceManagerClient( + 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 = DeviceManagerClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (DeviceManagerClient, transports.DeviceManagerGrpcTransport), + (DeviceManagerAsyncClient, transports.DeviceManagerGrpcAsyncIOTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + )