diff --git a/packages/google-cloud-videointelligence/.coveragerc b/packages/google-cloud-videointelligence/.coveragerc index bcbee4685022..fa73ede80a72 100644 --- a/packages/google-cloud-videointelligence/.coveragerc +++ b/packages/google-cloud-videointelligence/.coveragerc @@ -1,26 +1,11 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - [run] branch = True [report] fail_under = 100 show_missing = True -omit = google/cloud/texttospeech/__init__.py +omit = + google/cloud/videointelligence/__init__.py exclude_lines = # Re-enable the standard pragma pragma: NO COVER @@ -30,4 +15,4 @@ exclude_lines = # This is added at the module level as a safeguard for if someone # generates the code and tries to run it without pip installing. This # makes it virtually impossible to test properly. - except pkg_resources.DistributionNotFound \ No newline at end of file + except pkg_resources.DistributionNotFound diff --git a/packages/google-cloud-videointelligence/.github/header-checker-lint.yml b/packages/google-cloud-videointelligence/.github/header-checker-lint.yml new file mode 100644 index 000000000000..fc281c05bd55 --- /dev/null +++ b/packages/google-cloud-videointelligence/.github/header-checker-lint.yml @@ -0,0 +1,15 @@ +{"allowedCopyrightHolders": ["Google LLC"], + "allowedLicenses": ["Apache-2.0", "MIT", "BSD-3"], + "ignoreFiles": ["**/requirements.txt", "**/requirements-test.txt"], + "sourceFileExtensions": [ + "ts", + "js", + "java", + "sh", + "Dockerfile", + "yaml", + "py", + "html", + "txt" + ] +} \ No newline at end of file diff --git a/packages/google-cloud-videointelligence/.gitignore b/packages/google-cloud-videointelligence/.gitignore index b9daa52f118d..b4243ced74e4 100644 --- a/packages/google-cloud-videointelligence/.gitignore +++ b/packages/google-cloud-videointelligence/.gitignore @@ -50,8 +50,10 @@ docs.metadata # Virtual environment env/ + +# Test logs coverage.xml -sponge_log.xml +*sponge_log.xml # System test environment variables. system_tests/local_test_setup diff --git a/packages/google-cloud-videointelligence/.kokoro/build.sh b/packages/google-cloud-videointelligence/.kokoro/build.sh index 293b1c4daf00..9d4e94f4ba99 100755 --- a/packages/google-cloud-videointelligence/.kokoro/build.sh +++ b/packages/google-cloud-videointelligence/.kokoro/build.sh @@ -15,7 +15,11 @@ set -eo pipefail -cd github/python-videointelligence +if [[ -z "${PROJECT_ROOT:-}" ]]; then + PROJECT_ROOT="github/python-videointelligence" +fi + +cd "${PROJECT_ROOT}" # Disable buffering, so that the logs stream through. export PYTHONUNBUFFERED=1 @@ -30,16 +34,26 @@ export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json export PROJECT_ID=$(cat "${KOKORO_GFILE_DIR}/project-id.json") # Remove old nox -python3.6 -m pip uninstall --yes --quiet nox-automation +python3 -m pip uninstall --yes --quiet nox-automation # Install nox -python3.6 -m pip install --upgrade --quiet nox -python3.6 -m nox --version +python3 -m pip install --upgrade --quiet nox +python3 -m nox --version + +# If this is a continuous build, send the test log to the FlakyBot. +# See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. +if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]]; then + cleanup() { + chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot + $KOKORO_GFILE_DIR/linux_amd64/flakybot + } + trap cleanup EXIT HUP +fi # If NOX_SESSION is set, it only runs the specified session, # otherwise run all the sessions. if [[ -n "${NOX_SESSION:-}" ]]; then - python3.6 -m nox -s "${NOX_SESSION:-}" + python3 -m nox -s ${NOX_SESSION:-} else - python3.6 -m nox + python3 -m nox fi diff --git a/packages/google-cloud-videointelligence/.kokoro/docs/docs-presubmit.cfg b/packages/google-cloud-videointelligence/.kokoro/docs/docs-presubmit.cfg index 1118107829b7..b352270c98db 100644 --- a/packages/google-cloud-videointelligence/.kokoro/docs/docs-presubmit.cfg +++ b/packages/google-cloud-videointelligence/.kokoro/docs/docs-presubmit.cfg @@ -15,3 +15,14 @@ env_vars: { key: "TRAMPOLINE_IMAGE_UPLOAD" value: "false" } + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-videointelligence/.kokoro/build.sh" +} + +# Only run this nox session. +env_vars: { + key: "NOX_SESSION" + value: "docs docfx" +} diff --git a/packages/google-cloud-videointelligence/.kokoro/samples/python3.6/periodic-head.cfg b/packages/google-cloud-videointelligence/.kokoro/samples/python3.6/periodic-head.cfg new file mode 100644 index 000000000000..f9cfcd33e058 --- /dev/null +++ b/packages/google-cloud-videointelligence/.kokoro/samples/python3.6/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/packages/google-cloud-videointelligence/.kokoro/samples/python3.7/periodic-head.cfg b/packages/google-cloud-videointelligence/.kokoro/samples/python3.7/periodic-head.cfg new file mode 100644 index 000000000000..f9cfcd33e058 --- /dev/null +++ b/packages/google-cloud-videointelligence/.kokoro/samples/python3.7/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/packages/google-cloud-videointelligence/.kokoro/samples/python3.8/periodic-head.cfg b/packages/google-cloud-videointelligence/.kokoro/samples/python3.8/periodic-head.cfg new file mode 100644 index 000000000000..f9cfcd33e058 --- /dev/null +++ b/packages/google-cloud-videointelligence/.kokoro/samples/python3.8/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/packages/google-cloud-videointelligence/.kokoro/test-samples-against-head.sh b/packages/google-cloud-videointelligence/.kokoro/test-samples-against-head.sh new file mode 100755 index 000000000000..34b4d3fa2fe1 --- /dev/null +++ b/packages/google-cloud-videointelligence/.kokoro/test-samples-against-head.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# A customized test runner for samples. +# +# For periodic builds, you can specify this file for testing against head. + +# `-e` enables the script to automatically fail when a command fails +# `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero +set -eo pipefail +# Enables `**` to include files nested inside sub-folders +shopt -s globstar + +cd github/python-videointelligence + +exec .kokoro/test-samples-impl.sh diff --git a/packages/google-cloud-videointelligence/.kokoro/test-samples-impl.sh b/packages/google-cloud-videointelligence/.kokoro/test-samples-impl.sh new file mode 100755 index 000000000000..cf5de74c17a5 --- /dev/null +++ b/packages/google-cloud-videointelligence/.kokoro/test-samples-impl.sh @@ -0,0 +1,102 @@ +#!/bin/bash +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# `-e` enables the script to automatically fail when a command fails +# `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero +set -eo pipefail +# Enables `**` to include files nested inside sub-folders +shopt -s globstar + +# Exit early if samples directory doesn't exist +if [ ! -d "./samples" ]; then + echo "No tests run. `./samples` not found" + exit 0 +fi + +# Disable buffering, so that the logs stream through. +export PYTHONUNBUFFERED=1 + +# Debug: show build environment +env | grep KOKORO + +# Install nox +python3.6 -m pip install --upgrade --quiet nox + +# Use secrets acessor service account to get secrets +if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then + gcloud auth activate-service-account \ + --key-file="${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" \ + --project="cloud-devrel-kokoro-resources" +fi + +# This script will create 3 files: +# - testing/test-env.sh +# - testing/service-account.json +# - testing/client-secrets.json +./scripts/decrypt-secrets.sh + +source ./testing/test-env.sh +export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/testing/service-account.json + +# For cloud-run session, we activate the service account for gcloud sdk. +gcloud auth activate-service-account \ + --key-file "${GOOGLE_APPLICATION_CREDENTIALS}" + +export GOOGLE_CLIENT_SECRETS=$(pwd)/testing/client-secrets.json + +echo -e "\n******************** TESTING PROJECTS ********************" + +# Switch to 'fail at end' to allow all tests to complete before exiting. +set +e +# Use RTN to return a non-zero value if the test fails. +RTN=0 +ROOT=$(pwd) +# Find all requirements.txt in the samples directory (may break on whitespace). +for file in samples/**/requirements.txt; do + cd "$ROOT" + # Navigate to the project folder. + file=$(dirname "$file") + cd "$file" + + echo "------------------------------------------------------------" + echo "- testing $file" + echo "------------------------------------------------------------" + + # Use nox to execute the tests for the project. + python3.6 -m nox -s "$RUN_TESTS_SESSION" + EXIT=$? + + # If this is a periodic build, send the test log to the FlakyBot. + # See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. + if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then + chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot + $KOKORO_GFILE_DIR/linux_amd64/flakybot + fi + + if [[ $EXIT -ne 0 ]]; then + RTN=1 + echo -e "\n Testing failed: Nox returned a non-zero exit code. \n" + else + echo -e "\n Testing completed.\n" + fi + +done +cd "$ROOT" + +# Workaround for Kokoro permissions issue: delete secrets +rm testing/{test-env.sh,client-secrets.json,service-account.json} + +exit "$RTN" diff --git a/packages/google-cloud-videointelligence/.kokoro/test-samples.sh b/packages/google-cloud-videointelligence/.kokoro/test-samples.sh index 138821cbf701..0142da6759df 100755 --- a/packages/google-cloud-videointelligence/.kokoro/test-samples.sh +++ b/packages/google-cloud-videointelligence/.kokoro/test-samples.sh @@ -13,6 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +# The default test runner for samples. +# +# For periodic builds, we rewinds the repo to the latest release, and +# run test-samples-impl.sh. # `-e` enables the script to automatically fail when a command fails # `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero @@ -24,87 +28,19 @@ cd github/python-videointelligence # Run periodic samples tests at latest release if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then + # preserving the test runner implementation. + cp .kokoro/test-samples-impl.sh "${TMPDIR}/test-samples-impl.sh" + echo "--- IMPORTANT IMPORTANT IMPORTANT ---" + echo "Now we rewind the repo back to the latest release..." LATEST_RELEASE=$(git describe --abbrev=0 --tags) git checkout $LATEST_RELEASE -fi - -# Exit early if samples directory doesn't exist -if [ ! -d "./samples" ]; then - echo "No tests run. `./samples` not found" - exit 0 -fi - -# Disable buffering, so that the logs stream through. -export PYTHONUNBUFFERED=1 - -# Debug: show build environment -env | grep KOKORO - -# Install nox -python3.6 -m pip install --upgrade --quiet nox - -# Use secrets acessor service account to get secrets -if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then - gcloud auth activate-service-account \ - --key-file="${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" \ - --project="cloud-devrel-kokoro-resources" -fi - -# This script will create 3 files: -# - testing/test-env.sh -# - testing/service-account.json -# - testing/client-secrets.json -./scripts/decrypt-secrets.sh - -source ./testing/test-env.sh -export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/testing/service-account.json - -# For cloud-run session, we activate the service account for gcloud sdk. -gcloud auth activate-service-account \ - --key-file "${GOOGLE_APPLICATION_CREDENTIALS}" - -export GOOGLE_CLIENT_SECRETS=$(pwd)/testing/client-secrets.json - -echo -e "\n******************** TESTING PROJECTS ********************" - -# Switch to 'fail at end' to allow all tests to complete before exiting. -set +e -# Use RTN to return a non-zero value if the test fails. -RTN=0 -ROOT=$(pwd) -# Find all requirements.txt in the samples directory (may break on whitespace). -for file in samples/**/requirements.txt; do - cd "$ROOT" - # Navigate to the project folder. - file=$(dirname "$file") - cd "$file" - - echo "------------------------------------------------------------" - echo "- testing $file" - echo "------------------------------------------------------------" - - # Use nox to execute the tests for the project. - python3.6 -m nox -s "$RUN_TESTS_SESSION" - EXIT=$? - - # If this is a periodic build, send the test log to the FlakyBot. - # See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. - if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then - chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot - $KOKORO_GFILE_DIR/linux_amd64/flakybot + echo "The current head is: " + echo $(git rev-parse --verify HEAD) + echo "--- IMPORTANT IMPORTANT IMPORTANT ---" + # move back the test runner implementation if there's no file. + if [ ! -f .kokoro/test-samples-impl.sh ]; then + cp "${TMPDIR}/test-samples-impl.sh" .kokoro/test-samples-impl.sh fi +fi - if [[ $EXIT -ne 0 ]]; then - RTN=1 - echo -e "\n Testing failed: Nox returned a non-zero exit code. \n" - else - echo -e "\n Testing completed.\n" - fi - -done -cd "$ROOT" - -# Workaround for Kokoro permissions issue: delete secrets -rm testing/{test-env.sh,client-secrets.json,service-account.json} - -exit "$RTN" +exec .kokoro/test-samples-impl.sh diff --git a/packages/google-cloud-videointelligence/.pre-commit-config.yaml b/packages/google-cloud-videointelligence/.pre-commit-config.yaml index a9024b15d725..32302e4883a1 100644 --- a/packages/google-cloud-videointelligence/.pre-commit-config.yaml +++ b/packages/google-cloud-videointelligence/.pre-commit-config.yaml @@ -12,6 +12,6 @@ repos: hooks: - id: black - repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.4 + rev: 3.9.0 hooks: - id: flake8 diff --git a/packages/google-cloud-videointelligence/.trampolinerc b/packages/google-cloud-videointelligence/.trampolinerc index 995ee29111e1..383b6ec89fbc 100644 --- a/packages/google-cloud-videointelligence/.trampolinerc +++ b/packages/google-cloud-videointelligence/.trampolinerc @@ -24,6 +24,7 @@ required_envvars+=( pass_down_envvars+=( "STAGING_BUCKET" "V2_STAGING_BUCKET" + "NOX_SESSION" ) # Prevent unintentional override on the default image. diff --git a/packages/google-cloud-videointelligence/CONTRIBUTING.rst b/packages/google-cloud-videointelligence/CONTRIBUTING.rst index e6eb6ac1c745..92a026ea7edf 100644 --- a/packages/google-cloud-videointelligence/CONTRIBUTING.rst +++ b/packages/google-cloud-videointelligence/CONTRIBUTING.rst @@ -70,9 +70,14 @@ We use `nox `__ to instrument our tests. - To test your changes, run unit tests with ``nox``:: $ nox -s unit-2.7 - $ nox -s unit-3.7 + $ nox -s unit-3.8 $ ... +- Args to pytest can be passed through the nox command separated by a `--`. For + example, to run a single test:: + + $ nox -s unit-3.8 -- -k + .. note:: The unit tests and system tests are described in the @@ -93,8 +98,12 @@ On Debian/Ubuntu:: ************ Coding Style ************ +- We use the automatic code formatter ``black``. You can run it using + the nox session ``blacken``. This will eliminate many lint errors. Run via:: + + $ nox -s blacken -- PEP8 compliance, with exceptions defined in the linter configuration. +- PEP8 compliance is required, with exceptions defined in the linter configuration. If you have ``nox`` installed, you can test that you have not introduced any non-compliant code via:: @@ -133,13 +142,18 @@ Running System Tests - To run system tests, you can execute:: - $ nox -s system-3.7 + # Run all system tests + $ nox -s system-3.8 $ nox -s system-2.7 + # Run a single system test + $ nox -s system-3.8 -- -k + + .. note:: System tests are only configured to run under Python 2.7 and - Python 3.7. For expediency, we do not run them in older versions + Python 3.8. For expediency, we do not run them in older versions of Python 3. This alone will not run the tests. You'll need to change some local diff --git a/packages/google-cloud-videointelligence/LICENSE b/packages/google-cloud-videointelligence/LICENSE index a8ee855de2aa..d64569567334 100644 --- a/packages/google-cloud-videointelligence/LICENSE +++ b/packages/google-cloud-videointelligence/LICENSE @@ -1,6 +1,7 @@ - Apache License + + Apache License Version 2.0, January 2004 - https://www.apache.org/licenses/ + http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -192,7 +193,7 @@ you may not use this file except in compliance with the License. You may obtain a copy of the License at - https://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/packages/google-cloud-videointelligence/MANIFEST.in b/packages/google-cloud-videointelligence/MANIFEST.in index e9e29d12033d..e783f4c6209b 100644 --- a/packages/google-cloud-videointelligence/MANIFEST.in +++ b/packages/google-cloud-videointelligence/MANIFEST.in @@ -16,10 +16,10 @@ # Generated by synthtool. DO NOT EDIT! include README.rst LICENSE -recursive-include google *.json *.proto +recursive-include google *.json *.proto py.typed recursive-include tests * global-exclude *.py[co] global-exclude __pycache__ # Exclude scripts for samples readmegen -prune scripts/readme-gen \ No newline at end of file +prune scripts/readme-gen diff --git a/packages/google-cloud-videointelligence/docs/_static/custom.css b/packages/google-cloud-videointelligence/docs/_static/custom.css index 0abaf229fce3..bcd37bbd3c4a 100644 --- a/packages/google-cloud-videointelligence/docs/_static/custom.css +++ b/packages/google-cloud-videointelligence/docs/_static/custom.css @@ -1,4 +1,9 @@ div#python2-eol { border-color: red; border-width: medium; -} \ No newline at end of file +} + +/* Ensure minimum width for 'Parameters' / 'Returns' column */ +dl.field-list > dt { + min-width: 100px +} diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1/services.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1/services.rst index 8f9db9bb84a5..ed2a27c6650b 100644 --- a/packages/google-cloud-videointelligence/docs/videointelligence_v1/services.rst +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1/services.rst @@ -1,6 +1,6 @@ Services for Google Cloud Videointelligence v1 API ================================================== +.. toctree:: + :maxdepth: 2 -.. automodule:: google.cloud.videointelligence_v1.services.video_intelligence_service - :members: - :inherited-members: + video_intelligence_service diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1/types.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1/types.rst index b5d39277f4fd..6bada0024613 100644 --- a/packages/google-cloud-videointelligence/docs/videointelligence_v1/types.rst +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1/types.rst @@ -3,4 +3,5 @@ Types for Google Cloud Videointelligence v1 API .. automodule:: google.cloud.videointelligence_v1.types :members: + :undoc-members: :show-inheritance: diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1/video_intelligence_service.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1/video_intelligence_service.rst new file mode 100644 index 000000000000..d8d38ca3239c --- /dev/null +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1/video_intelligence_service.rst @@ -0,0 +1,6 @@ +VideoIntelligenceService +------------------------------------------ + +.. automodule:: google.cloud.videointelligence_v1.services.video_intelligence_service + :members: + :inherited-members: diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1beta2/services.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1beta2/services.rst index 751201903467..c8f45a1e0e37 100644 --- a/packages/google-cloud-videointelligence/docs/videointelligence_v1beta2/services.rst +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1beta2/services.rst @@ -1,6 +1,6 @@ Services for Google Cloud Videointelligence v1beta2 API ======================================================= +.. toctree:: + :maxdepth: 2 -.. automodule:: google.cloud.videointelligence_v1beta2.services.video_intelligence_service - :members: - :inherited-members: + video_intelligence_service diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1beta2/types.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1beta2/types.rst index 47f60c25e451..62921eacf723 100644 --- a/packages/google-cloud-videointelligence/docs/videointelligence_v1beta2/types.rst +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1beta2/types.rst @@ -3,4 +3,5 @@ Types for Google Cloud Videointelligence v1beta2 API .. automodule:: google.cloud.videointelligence_v1beta2.types :members: + :undoc-members: :show-inheritance: diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1beta2/video_intelligence_service.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1beta2/video_intelligence_service.rst new file mode 100644 index 000000000000..ab6c31d31e6d --- /dev/null +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1beta2/video_intelligence_service.rst @@ -0,0 +1,6 @@ +VideoIntelligenceService +------------------------------------------ + +.. automodule:: google.cloud.videointelligence_v1beta2.services.video_intelligence_service + :members: + :inherited-members: diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1p1beta1/services.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1p1beta1/services.rst index 51e86ba2b691..a26a19fe3861 100644 --- a/packages/google-cloud-videointelligence/docs/videointelligence_v1p1beta1/services.rst +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1p1beta1/services.rst @@ -1,6 +1,6 @@ Services for Google Cloud Videointelligence v1p1beta1 API ========================================================= +.. toctree:: + :maxdepth: 2 -.. automodule:: google.cloud.videointelligence_v1p1beta1.services.video_intelligence_service - :members: - :inherited-members: + video_intelligence_service diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1p1beta1/types.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1p1beta1/types.rst index e9c681c58510..2aa52bbf8fc5 100644 --- a/packages/google-cloud-videointelligence/docs/videointelligence_v1p1beta1/types.rst +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1p1beta1/types.rst @@ -3,4 +3,5 @@ Types for Google Cloud Videointelligence v1p1beta1 API .. automodule:: google.cloud.videointelligence_v1p1beta1.types :members: + :undoc-members: :show-inheritance: diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1p1beta1/video_intelligence_service.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1p1beta1/video_intelligence_service.rst new file mode 100644 index 000000000000..423a835c5b25 --- /dev/null +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1p1beta1/video_intelligence_service.rst @@ -0,0 +1,6 @@ +VideoIntelligenceService +------------------------------------------ + +.. automodule:: google.cloud.videointelligence_v1p1beta1.services.video_intelligence_service + :members: + :inherited-members: diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1p2beta1/services.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1p2beta1/services.rst index f4258599b380..e3029604fd1b 100644 --- a/packages/google-cloud-videointelligence/docs/videointelligence_v1p2beta1/services.rst +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1p2beta1/services.rst @@ -1,6 +1,6 @@ Services for Google Cloud Videointelligence v1p2beta1 API ========================================================= +.. toctree:: + :maxdepth: 2 -.. automodule:: google.cloud.videointelligence_v1p2beta1.services.video_intelligence_service - :members: - :inherited-members: + video_intelligence_service diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1p2beta1/types.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1p2beta1/types.rst index 30c5462f5f14..1825803c6c3a 100644 --- a/packages/google-cloud-videointelligence/docs/videointelligence_v1p2beta1/types.rst +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1p2beta1/types.rst @@ -3,4 +3,5 @@ Types for Google Cloud Videointelligence v1p2beta1 API .. automodule:: google.cloud.videointelligence_v1p2beta1.types :members: + :undoc-members: :show-inheritance: diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1p2beta1/video_intelligence_service.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1p2beta1/video_intelligence_service.rst new file mode 100644 index 000000000000..804a5442a150 --- /dev/null +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1p2beta1/video_intelligence_service.rst @@ -0,0 +1,6 @@ +VideoIntelligenceService +------------------------------------------ + +.. automodule:: google.cloud.videointelligence_v1p2beta1.services.video_intelligence_service + :members: + :inherited-members: diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/services.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/services.rst index 0a2b15bd3a6c..853cb921e507 100644 --- a/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/services.rst +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/services.rst @@ -1,9 +1,7 @@ Services for Google Cloud Videointelligence v1p3beta1 API ========================================================= +.. toctree:: + :maxdepth: 2 -.. automodule:: google.cloud.videointelligence_v1p3beta1.services.streaming_video_intelligence_service - :members: - :inherited-members: -.. automodule:: google.cloud.videointelligence_v1p3beta1.services.video_intelligence_service - :members: - :inherited-members: + streaming_video_intelligence_service + video_intelligence_service diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/streaming_video_intelligence_service.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/streaming_video_intelligence_service.rst new file mode 100644 index 000000000000..4de59243fb0c --- /dev/null +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/streaming_video_intelligence_service.rst @@ -0,0 +1,6 @@ +StreamingVideoIntelligenceService +--------------------------------------------------- + +.. automodule:: google.cloud.videointelligence_v1p3beta1.services.streaming_video_intelligence_service + :members: + :inherited-members: diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/types.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/types.rst index 4305d5882042..75c97809cd1e 100644 --- a/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/types.rst +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/types.rst @@ -3,4 +3,5 @@ Types for Google Cloud Videointelligence v1p3beta1 API .. automodule:: google.cloud.videointelligence_v1p3beta1.types :members: + :undoc-members: :show-inheritance: diff --git a/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/video_intelligence_service.rst b/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/video_intelligence_service.rst new file mode 100644 index 000000000000..fd06a1996f49 --- /dev/null +++ b/packages/google-cloud-videointelligence/docs/videointelligence_v1p3beta1/video_intelligence_service.rst @@ -0,0 +1,6 @@ +VideoIntelligenceService +------------------------------------------ + +.. automodule:: google.cloud.videointelligence_v1p3beta1.services.video_intelligence_service + :members: + :inherited-members: diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/async_client.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/async_client.py index e4e0e5428786..a0030e47c351 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/async_client.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/async_client.py @@ -78,7 +78,36 @@ class VideoIntelligenceServiceAsyncClient: VideoIntelligenceServiceClient.parse_common_location_path ) - from_service_account_file = VideoIntelligenceServiceClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceAsyncClient: The constructed client. + """ + return VideoIntelligenceServiceClient.from_service_account_info.__func__(VideoIntelligenceServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceAsyncClient: The constructed client. + """ + return VideoIntelligenceServiceClient.from_service_account_file.__func__(VideoIntelligenceServiceAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property @@ -160,7 +189,7 @@ async def annotate_video( contains ``AnnotateVideoResponse`` (results). Args: - request (:class:`~.video_intelligence.AnnotateVideoRequest`): + request (:class:`google.cloud.videointelligence_v1.types.AnnotateVideoRequest`): The request object. Video annotation request. input_uri (:class:`str`): Input video location. Currently, only `Cloud @@ -177,12 +206,14 @@ async def annotate_video( If unset, the input video should be embedded in the request as ``input_content``. If set, ``input_content`` must be unset. + This corresponds to the ``input_uri`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - features (:class:`Sequence[~.video_intelligence.Feature]`): + features (:class:`Sequence[google.cloud.videointelligence_v1.types.Feature]`): Required. Requested video annotation features. + This corresponds to the ``features`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -194,15 +225,12 @@ async def annotate_video( sent along with the request as metadata. Returns: - ~.operation_async.AsyncOperation: + google.api_core.operation_async.AsyncOperation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.video_intelligence.AnnotateVideoResponse``: - Video annotation response. Included in the ``response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.videointelligence_v1.types.AnnotateVideoResponse` Video annotation response. Included in the response + field of the Operation returned by the GetOperation + call of the google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -237,6 +265,7 @@ async def annotate_video( predicate=retries.if_exception_type( exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), + deadline=600.0, ), default_timeout=600.0, client_info=DEFAULT_CLIENT_INFO, diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/client.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/client.py index 88b3c34c1fcb..387158858a41 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/client.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/client.py @@ -113,6 +113,22 @@ def _get_default_mtls_endpoint(api_endpoint): DEFAULT_ENDPOINT ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -125,7 +141,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): kwargs: Additional arguments to pass to the constructor. Returns: - {@api.name}: The constructed client. + VideoIntelligenceServiceClient: The constructed client. """ credentials = service_account.Credentials.from_service_account_file(filename) kwargs["credentials"] = credentials @@ -217,10 +233,10 @@ def __init__( credentials identify the application to the service; if none are specified, the client will attempt to ascertain the credentials from the environment. - transport (Union[str, ~.VideoIntelligenceServiceTransport]): The + transport (Union[str, VideoIntelligenceServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the + client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT @@ -256,21 +272,17 @@ def __init__( util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) ) - ssl_credentials = None + client_cert_source_func = None is_mtls = False if use_client_cert: if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) is_mtls = True + client_cert_source_func = client_options.client_cert_source else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None + is_mtls = mtls.has_default_client_cert_source() + client_cert_source_func = ( + mtls.default_client_cert_source() if is_mtls else None + ) # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -313,7 +325,7 @@ def __init__( credentials_file=client_options.credentials_file, host=api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, ) @@ -335,9 +347,9 @@ def annotate_video( contains ``AnnotateVideoResponse`` (results). Args: - request (:class:`~.video_intelligence.AnnotateVideoRequest`): + request (google.cloud.videointelligence_v1.types.AnnotateVideoRequest): The request object. Video annotation request. - input_uri (:class:`str`): + input_uri (str): Input video location. Currently, only `Cloud Storage `__ URIs are supported. URIs must be specified in the following @@ -352,12 +364,14 @@ def annotate_video( If unset, the input video should be embedded in the request as ``input_content``. If set, ``input_content`` must be unset. + This corresponds to the ``input_uri`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - features (:class:`Sequence[~.video_intelligence.Feature]`): + features (Sequence[google.cloud.videointelligence_v1.types.Feature]): Required. Requested video annotation features. + This corresponds to the ``features`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -369,15 +383,12 @@ def annotate_video( sent along with the request as metadata. Returns: - ~.operation.Operation: + google.api_core.operation.Operation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.video_intelligence.AnnotateVideoResponse``: - Video annotation response. Included in the ``response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.videointelligence_v1.types.AnnotateVideoResponse` Video annotation response. Included in the response + field of the Operation returned by the GetOperation + call of the google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -402,9 +413,8 @@ def annotate_video( if input_uri is not None: request.input_uri = input_uri - - if features: - request.features.extend(features) + if features is not None: + request.features = features # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/base.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/base.py index c2764892ca07..c0b9f3fd19e9 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/base.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/base.py @@ -71,10 +71,10 @@ def __init__( scope (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. """ # Save the hostname. Default to port 443 (HTTPS) if none is specified. @@ -82,6 +82,9 @@ def __init__( host += ":443" self._host = host + # Save the scopes. + self._scopes = scopes or self.AUTH_SCOPES + # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: @@ -91,20 +94,17 @@ def __init__( if credentials_file is not None: credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=scopes, quota_project_id=quota_project_id + credentials_file, scopes=self._scopes, quota_project_id=quota_project_id ) elif credentials is None: credentials, _ = auth.default( - scopes=scopes, quota_project_id=quota_project_id + scopes=self._scopes, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials - # Lifted into its own function so it can be stubbed out during tests. - self._prep_wrapped_messages(client_info) - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -117,6 +117,7 @@ def _prep_wrapped_messages(self, client_info): predicate=retries.if_exception_type( exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), + deadline=600.0, ), default_timeout=600.0, client_info=client_info, diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc.py index ce7eac22e87f..6d7952b9b1a6 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc.py @@ -59,6 +59,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -89,6 +90,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -103,72 +108,61 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -176,18 +170,8 @@ def __init__( ], ) - self._stubs = {} # type: Dict[str, Callable] - self._operations_client = None - - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @classmethod def create_channel( @@ -201,7 +185,7 @@ def create_channel( ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc_asyncio.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc_asyncio.py index 6d989c85a93a..0a957cf2188e 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc_asyncio.py @@ -63,7 +63,7 @@ def create_channel( ) -> aio.Channel: """Create and return a gRPC AsyncIO channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If @@ -103,6 +103,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -134,12 +135,16 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -148,72 +153,61 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -221,18 +215,8 @@ def __init__( ], ) - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) - - self._stubs = {} - self._operations_client = None + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @property def grpc_channel(self) -> aio.Channel: diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/types/__init__.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/types/__init__.py index a39f7bd2c29f..745051059dd1 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/types/__init__.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/types/__init__.py @@ -16,98 +16,98 @@ # from .video_intelligence import ( + AnnotateVideoProgress, AnnotateVideoRequest, - VideoContext, - LabelDetectionConfig, - ShotChangeDetectionConfig, - ObjectTrackingConfig, - FaceDetectionConfig, - PersonDetectionConfig, - ExplicitContentDetectionConfig, - TextDetectionConfig, - VideoSegment, - LabelSegment, - LabelFrame, + AnnotateVideoResponse, + DetectedAttribute, + DetectedLandmark, Entity, - LabelAnnotation, - ExplicitContentFrame, ExplicitContentAnnotation, - NormalizedBoundingBox, + ExplicitContentDetectionConfig, + ExplicitContentFrame, + FaceAnnotation, FaceDetectionAnnotation, - PersonDetectionAnnotation, - FaceSegment, + FaceDetectionConfig, FaceFrame, - FaceAnnotation, + FaceSegment, + LabelAnnotation, + LabelDetectionConfig, + LabelFrame, + LabelSegment, + LogoRecognitionAnnotation, + NormalizedBoundingBox, + NormalizedBoundingPoly, + NormalizedVertex, + ObjectTrackingAnnotation, + ObjectTrackingConfig, + ObjectTrackingFrame, + PersonDetectionAnnotation, + PersonDetectionConfig, + ShotChangeDetectionConfig, + SpeechContext, + SpeechRecognitionAlternative, + SpeechTranscription, + SpeechTranscriptionConfig, + TextAnnotation, + TextDetectionConfig, + TextFrame, + TextSegment, TimestampedObject, Track, - DetectedAttribute, - DetectedLandmark, - VideoAnnotationResults, - AnnotateVideoResponse, VideoAnnotationProgress, - AnnotateVideoProgress, - SpeechTranscriptionConfig, - SpeechContext, - SpeechTranscription, - SpeechRecognitionAlternative, + VideoAnnotationResults, + VideoContext, + VideoSegment, WordInfo, - NormalizedVertex, - NormalizedBoundingPoly, - TextSegment, - TextFrame, - TextAnnotation, - ObjectTrackingFrame, - ObjectTrackingAnnotation, - LogoRecognitionAnnotation, Feature, LabelDetectionMode, Likelihood, ) __all__ = ( + "AnnotateVideoProgress", "AnnotateVideoRequest", - "VideoContext", - "LabelDetectionConfig", - "ShotChangeDetectionConfig", - "ObjectTrackingConfig", - "FaceDetectionConfig", - "PersonDetectionConfig", - "ExplicitContentDetectionConfig", - "TextDetectionConfig", - "VideoSegment", - "LabelSegment", - "LabelFrame", + "AnnotateVideoResponse", + "DetectedAttribute", + "DetectedLandmark", "Entity", - "LabelAnnotation", - "ExplicitContentFrame", "ExplicitContentAnnotation", - "NormalizedBoundingBox", + "ExplicitContentDetectionConfig", + "ExplicitContentFrame", + "FaceAnnotation", "FaceDetectionAnnotation", - "PersonDetectionAnnotation", - "FaceSegment", + "FaceDetectionConfig", "FaceFrame", - "FaceAnnotation", + "FaceSegment", + "LabelAnnotation", + "LabelDetectionConfig", + "LabelFrame", + "LabelSegment", + "LogoRecognitionAnnotation", + "NormalizedBoundingBox", + "NormalizedBoundingPoly", + "NormalizedVertex", + "ObjectTrackingAnnotation", + "ObjectTrackingConfig", + "ObjectTrackingFrame", + "PersonDetectionAnnotation", + "PersonDetectionConfig", + "ShotChangeDetectionConfig", + "SpeechContext", + "SpeechRecognitionAlternative", + "SpeechTranscription", + "SpeechTranscriptionConfig", + "TextAnnotation", + "TextDetectionConfig", + "TextFrame", + "TextSegment", "TimestampedObject", "Track", - "DetectedAttribute", - "DetectedLandmark", - "VideoAnnotationResults", - "AnnotateVideoResponse", "VideoAnnotationProgress", - "AnnotateVideoProgress", - "SpeechTranscriptionConfig", - "SpeechContext", - "SpeechTranscription", - "SpeechRecognitionAlternative", + "VideoAnnotationResults", + "VideoContext", + "VideoSegment", "WordInfo", - "NormalizedVertex", - "NormalizedBoundingPoly", - "TextSegment", - "TextFrame", - "TextAnnotation", - "ObjectTrackingFrame", - "ObjectTrackingAnnotation", - "LogoRecognitionAnnotation", "Feature", "LabelDetectionMode", "Likelihood", diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/types/video_intelligence.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/types/video_intelligence.py index 7586ed64c6ed..ece4d6404375 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/types/video_intelligence.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1/types/video_intelligence.py @@ -129,10 +129,10 @@ class AnnotateVideoRequest(proto.Message): The video data bytes. If unset, the input video(s) should be specified via the ``input_uri``. If set, ``input_uri`` must be unset. - features (Sequence[~.video_intelligence.Feature]): + features (Sequence[google.cloud.videointelligence_v1.types.Feature]): Required. Requested video annotation features. - video_context (~.video_intelligence.VideoContext): + video_context (google.cloud.videointelligence_v1.types.VideoContext): Additional video context and/or feature- pecific parameters. output_uri (str): @@ -168,26 +168,26 @@ class VideoContext(proto.Message): r"""Video context and/or feature-specific parameters. Attributes: - segments (Sequence[~.video_intelligence.VideoSegment]): + segments (Sequence[google.cloud.videointelligence_v1.types.VideoSegment]): Video segments to annotate. The segments may overlap and are not required to be contiguous or span the whole video. If unspecified, each video is treated as a single segment. - label_detection_config (~.video_intelligence.LabelDetectionConfig): + label_detection_config (google.cloud.videointelligence_v1.types.LabelDetectionConfig): Config for LABEL_DETECTION. - shot_change_detection_config (~.video_intelligence.ShotChangeDetectionConfig): + shot_change_detection_config (google.cloud.videointelligence_v1.types.ShotChangeDetectionConfig): Config for SHOT_CHANGE_DETECTION. - explicit_content_detection_config (~.video_intelligence.ExplicitContentDetectionConfig): + explicit_content_detection_config (google.cloud.videointelligence_v1.types.ExplicitContentDetectionConfig): Config for EXPLICIT_CONTENT_DETECTION. - face_detection_config (~.video_intelligence.FaceDetectionConfig): + face_detection_config (google.cloud.videointelligence_v1.types.FaceDetectionConfig): Config for FACE_DETECTION. - speech_transcription_config (~.video_intelligence.SpeechTranscriptionConfig): + speech_transcription_config (google.cloud.videointelligence_v1.types.SpeechTranscriptionConfig): Config for SPEECH_TRANSCRIPTION. - text_detection_config (~.video_intelligence.TextDetectionConfig): + text_detection_config (google.cloud.videointelligence_v1.types.TextDetectionConfig): Config for TEXT_DETECTION. - person_detection_config (~.video_intelligence.PersonDetectionConfig): + person_detection_config (google.cloud.videointelligence_v1.types.PersonDetectionConfig): Config for PERSON_DETECTION. - object_tracking_config (~.video_intelligence.ObjectTrackingConfig): + object_tracking_config (google.cloud.videointelligence_v1.types.ObjectTrackingConfig): Config for OBJECT_TRACKING. """ @@ -230,7 +230,7 @@ class LabelDetectionConfig(proto.Message): r"""Config for LABEL_DETECTION. Attributes: - label_detection_mode (~.video_intelligence.LabelDetectionMode): + label_detection_mode (google.cloud.videointelligence_v1.types.LabelDetectionMode): What labels should be detected with LABEL_DETECTION, in addition to video-level labels or segment-level labels. If unspecified, defaults to ``SHOT_MODE``. @@ -387,11 +387,11 @@ class VideoSegment(proto.Message): r"""Video segment. Attributes: - start_time_offset (~.duration.Duration): + start_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the start of the segment (inclusive). - end_time_offset (~.duration.Duration): + end_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the end of the segment (inclusive). @@ -406,7 +406,7 @@ class LabelSegment(proto.Message): r"""Video segment level annotation results for label detection. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1.types.VideoSegment): Video segment where a label was detected. confidence (float): Confidence that the label is accurate. Range: [0, 1]. @@ -421,7 +421,7 @@ class LabelFrame(proto.Message): r"""Video frame level annotation results for label detection. Attributes: - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this location. @@ -459,17 +459,17 @@ class LabelAnnotation(proto.Message): r"""Label annotation. Attributes: - entity (~.video_intelligence.Entity): + entity (google.cloud.videointelligence_v1.types.Entity): Detected entity. - category_entities (Sequence[~.video_intelligence.Entity]): + category_entities (Sequence[google.cloud.videointelligence_v1.types.Entity]): Common categories for the detected entity. For example, when the label is ``Terrier``, the category is likely ``dog``. And in some cases there might be more than one categories e.g., ``Terrier`` could also be a ``pet``. - segments (Sequence[~.video_intelligence.LabelSegment]): + segments (Sequence[google.cloud.videointelligence_v1.types.LabelSegment]): All video segments where a label was detected. - frames (Sequence[~.video_intelligence.LabelFrame]): + frames (Sequence[google.cloud.videointelligence_v1.types.LabelFrame]): All video frames where a label was detected. version (str): Feature version. @@ -490,11 +490,11 @@ class ExplicitContentFrame(proto.Message): r"""Video frame level annotation results for explicit content. Attributes: - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this location. - pornography_likelihood (~.video_intelligence.Likelihood): + pornography_likelihood (google.cloud.videointelligence_v1.types.Likelihood): Likelihood of the pornography content.. """ @@ -509,7 +509,7 @@ class ExplicitContentAnnotation(proto.Message): frame, no annotations are present for that frame. Attributes: - frames (Sequence[~.video_intelligence.ExplicitContentFrame]): + frames (Sequence[google.cloud.videointelligence_v1.types.ExplicitContentFrame]): All video frames where explicit content was detected. version (str): @@ -551,7 +551,7 @@ class FaceDetectionAnnotation(proto.Message): r"""Face detection annotation. Attributes: - tracks (Sequence[~.video_intelligence.Track]): + tracks (Sequence[google.cloud.videointelligence_v1.types.Track]): The face tracks with attributes. thumbnail (bytes): The thumbnail of a person's face. @@ -570,7 +570,7 @@ class PersonDetectionAnnotation(proto.Message): r"""Person detection annotation per video. Attributes: - tracks (Sequence[~.video_intelligence.Track]): + tracks (Sequence[google.cloud.videointelligence_v1.types.Track]): The detected tracks of a person. version (str): Feature version. @@ -585,7 +585,7 @@ class FaceSegment(proto.Message): r"""Video segment level annotation results for face detection. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1.types.VideoSegment): Video segment where a face was detected. """ @@ -596,12 +596,12 @@ class FaceFrame(proto.Message): r"""Deprecated. No effect. Attributes: - normalized_bounding_boxes (Sequence[~.video_intelligence.NormalizedBoundingBox]): + normalized_bounding_boxes (Sequence[google.cloud.videointelligence_v1.types.NormalizedBoundingBox]): Normalized Bounding boxes in a frame. There can be more than one boxes if the same face is detected in multiple locations within the current frame. - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this location. @@ -621,9 +621,9 @@ class FaceAnnotation(proto.Message): thumbnail (bytes): Thumbnail of a representative face view (in JPEG format). - segments (Sequence[~.video_intelligence.FaceSegment]): + segments (Sequence[google.cloud.videointelligence_v1.types.FaceSegment]): All video segments where a face was detected. - frames (Sequence[~.video_intelligence.FaceFrame]): + frames (Sequence[google.cloud.videointelligence_v1.types.FaceFrame]): All video frames where a face was detected. """ @@ -639,17 +639,17 @@ class TimestampedObject(proto.Message): attributes, and located with normalized_bounding_box. Attributes: - normalized_bounding_box (~.video_intelligence.NormalizedBoundingBox): + normalized_bounding_box (google.cloud.videointelligence_v1.types.NormalizedBoundingBox): Normalized Bounding box in a frame, where the object is located. - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this object. - attributes (Sequence[~.video_intelligence.DetectedAttribute]): + attributes (Sequence[google.cloud.videointelligence_v1.types.DetectedAttribute]): Optional. The attributes of the object in the bounding box. - landmarks (Sequence[~.video_intelligence.DetectedLandmark]): + landmarks (Sequence[google.cloud.videointelligence_v1.types.DetectedLandmark]): Optional. The detected landmarks. """ @@ -672,12 +672,12 @@ class Track(proto.Message): r"""A track of an object instance. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1.types.VideoSegment): Video segment of a track. - timestamped_objects (Sequence[~.video_intelligence.TimestampedObject]): + timestamped_objects (Sequence[google.cloud.videointelligence_v1.types.TimestampedObject]): The object with timestamp and attributes per frame in the track. - attributes (Sequence[~.video_intelligence.DetectedAttribute]): + attributes (Sequence[google.cloud.videointelligence_v1.types.DetectedAttribute]): Optional. Attributes in the track level. confidence (float): Optional. The confidence score of the tracked @@ -729,7 +729,7 @@ class DetectedLandmark(proto.Message): name (str): The name of this landmark, for example, left_hand, right_shoulder. - point (~.video_intelligence.NormalizedVertex): + point (google.cloud.videointelligence_v1.types.NormalizedVertex): The 2D point of the detected landmark using the normalized image coordindate system. The normalized coordinates have the range from 0 to @@ -752,13 +752,13 @@ class VideoAnnotationResults(proto.Message): input_uri (str): Video file location in `Cloud Storage `__. - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1.types.VideoSegment): Video segment on which the annotation is run. - segment_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + segment_label_annotations (Sequence[google.cloud.videointelligence_v1.types.LabelAnnotation]): Topical label annotations on video level or user-specified segment level. There is exactly one element for each unique label. - segment_presence_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + segment_presence_label_annotations (Sequence[google.cloud.videointelligence_v1.types.LabelAnnotation]): Presence label annotations on video level or user-specified segment level. There is exactly one element for each unique label. Compared to the existing topical @@ -767,11 +767,11 @@ class VideoAnnotationResults(proto.Message): and is made available only when the client sets ``LabelDetectionConfig.model`` to "builtin/latest" in the request. - shot_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + shot_label_annotations (Sequence[google.cloud.videointelligence_v1.types.LabelAnnotation]): Topical label annotations on shot level. There is exactly one element for each unique label. - shot_presence_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + shot_presence_label_annotations (Sequence[google.cloud.videointelligence_v1.types.LabelAnnotation]): Presence label annotations on shot level. There is exactly one element for each unique label. Compared to the existing topical ``shot_label_annotations``, this field presents more @@ -779,36 +779,36 @@ class VideoAnnotationResults(proto.Message): and is made available only when the client sets ``LabelDetectionConfig.model`` to "builtin/latest" in the request. - frame_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + frame_label_annotations (Sequence[google.cloud.videointelligence_v1.types.LabelAnnotation]): Label annotations on frame level. There is exactly one element for each unique label. - face_annotations (Sequence[~.video_intelligence.FaceAnnotation]): + face_annotations (Sequence[google.cloud.videointelligence_v1.types.FaceAnnotation]): Deprecated. Please use ``face_detection_annotations`` instead. - face_detection_annotations (Sequence[~.video_intelligence.FaceDetectionAnnotation]): + face_detection_annotations (Sequence[google.cloud.videointelligence_v1.types.FaceDetectionAnnotation]): Face detection annotations. - shot_annotations (Sequence[~.video_intelligence.VideoSegment]): + shot_annotations (Sequence[google.cloud.videointelligence_v1.types.VideoSegment]): Shot annotations. Each shot is represented as a video segment. - explicit_annotation (~.video_intelligence.ExplicitContentAnnotation): + explicit_annotation (google.cloud.videointelligence_v1.types.ExplicitContentAnnotation): Explicit content annotation. - speech_transcriptions (Sequence[~.video_intelligence.SpeechTranscription]): + speech_transcriptions (Sequence[google.cloud.videointelligence_v1.types.SpeechTranscription]): Speech transcription. - text_annotations (Sequence[~.video_intelligence.TextAnnotation]): + text_annotations (Sequence[google.cloud.videointelligence_v1.types.TextAnnotation]): OCR text detection and tracking. Annotations for list of detected text snippets. Each will have list of frame information associated with it. - object_annotations (Sequence[~.video_intelligence.ObjectTrackingAnnotation]): + object_annotations (Sequence[google.cloud.videointelligence_v1.types.ObjectTrackingAnnotation]): Annotations for list of objects detected and tracked in video. - logo_recognition_annotations (Sequence[~.video_intelligence.LogoRecognitionAnnotation]): + logo_recognition_annotations (Sequence[google.cloud.videointelligence_v1.types.LogoRecognitionAnnotation]): Annotations for list of logos detected, tracked and recognized in video. - person_detection_annotations (Sequence[~.video_intelligence.PersonDetectionAnnotation]): + person_detection_annotations (Sequence[google.cloud.videointelligence_v1.types.PersonDetectionAnnotation]): Person detection annotations. - error (~.status.Status): + error (google.rpc.status_pb2.Status): If set, indicates an error. Note that for a single ``AnnotateVideoRequest`` some videos may succeed and some may fail. @@ -883,7 +883,7 @@ class AnnotateVideoResponse(proto.Message): ``google::longrunning::Operations`` service. Attributes: - annotation_results (Sequence[~.video_intelligence.VideoAnnotationResults]): + annotation_results (Sequence[google.cloud.videointelligence_v1.types.VideoAnnotationResults]): Annotation results for all videos specified in ``AnnotateVideoRequest``. """ @@ -903,14 +903,14 @@ class VideoAnnotationProgress(proto.Message): progress_percent (int): Approximate percentage processed thus far. Guaranteed to be 100 when fully processed. - start_time (~.timestamp.Timestamp): + start_time (google.protobuf.timestamp_pb2.Timestamp): Time when the request was received. - update_time (~.timestamp.Timestamp): + update_time (google.protobuf.timestamp_pb2.Timestamp): Time of the most recent update. - feature (~.video_intelligence.Feature): + feature (google.cloud.videointelligence_v1.types.Feature): Specifies which feature is being tracked if the request contains more than one feature. - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1.types.VideoSegment): Specifies which segment is being tracked if the request contains more than one segment. """ @@ -934,7 +934,7 @@ class AnnotateVideoProgress(proto.Message): ``google::longrunning::Operations`` service. Attributes: - annotation_progress (Sequence[~.video_intelligence.VideoAnnotationProgress]): + annotation_progress (Sequence[google.cloud.videointelligence_v1.types.VideoAnnotationProgress]): Progress metadata for all videos specified in ``AnnotateVideoRequest``. """ @@ -968,7 +968,7 @@ class SpeechTranscriptionConfig(proto.Message): character in each filtered word with asterisks, e.g. "f***". If set to ``false`` or omitted, profanities won't be filtered out. - speech_contexts (Sequence[~.video_intelligence.SpeechContext]): + speech_contexts (Sequence[google.cloud.videointelligence_v1.types.SpeechContext]): Optional. A means to provide context to assist the speech recognition. enable_automatic_punctuation (bool): @@ -1051,7 +1051,7 @@ class SpeechTranscription(proto.Message): audio. Attributes: - alternatives (Sequence[~.video_intelligence.SpeechRecognitionAlternative]): + alternatives (Sequence[google.cloud.videointelligence_v1.types.SpeechRecognitionAlternative]): May contain one or more recognition hypotheses (up to the maximum specified in ``max_alternatives``). These alternatives are ordered in terms of accuracy, with the top @@ -1087,7 +1087,7 @@ class SpeechRecognitionAlternative(proto.Message): accurate and users should not rely on it to be always provided. The default of 0.0 is a sentinel value indicating ``confidence`` was not set. - words (Sequence[~.video_intelligence.WordInfo]): + words (Sequence[google.cloud.videointelligence_v1.types.WordInfo]): Output only. A list of word-specific information for each recognized word. Note: When ``enable_speaker_diarization`` is set to true, you will see all the words from the @@ -1107,13 +1107,13 @@ class WordInfo(proto.Message): set, such as ``enable_word_time_offsets``. Attributes: - start_time (~.duration.Duration): + start_time (google.protobuf.duration_pb2.Duration): Time offset relative to the beginning of the audio, and corresponding to the start of the spoken word. This field is only set if ``enable_word_time_offsets=true`` and only in the top hypothesis. This is an experimental feature and the accuracy of the time offset can vary. - end_time (~.duration.Duration): + end_time (google.protobuf.duration_pb2.Duration): Time offset relative to the beginning of the audio, and corresponding to the end of the spoken word. This field is only set if ``enable_word_time_offsets=true`` and only in @@ -1181,7 +1181,7 @@ class NormalizedBoundingPoly(proto.Message): calculations for location of the box. Attributes: - vertices (Sequence[~.video_intelligence.NormalizedVertex]): + vertices (Sequence[google.cloud.videointelligence_v1.types.NormalizedVertex]): Normalized vertices of the bounding polygon. """ @@ -1192,14 +1192,14 @@ class TextSegment(proto.Message): r"""Video segment level annotation results for text detection. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1.types.VideoSegment): Video segment where a text snippet was detected. confidence (float): Confidence for the track of detected text. It is calculated as the highest over all frames where OCR detected text appears. - frames (Sequence[~.video_intelligence.TextFrame]): + frames (Sequence[google.cloud.videointelligence_v1.types.TextFrame]): Information related to the frames where OCR detected text appears. """ @@ -1217,10 +1217,10 @@ class TextFrame(proto.Message): locations for the frames containing detected OCR text snippets. Attributes: - rotated_bounding_box (~.video_intelligence.NormalizedBoundingPoly): + rotated_bounding_box (google.cloud.videointelligence_v1.types.NormalizedBoundingPoly): Bounding polygon of the detected text for this frame. - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Timestamp of this frame. """ @@ -1239,7 +1239,7 @@ class TextAnnotation(proto.Message): Attributes: text (str): The detected text. - segments (Sequence[~.video_intelligence.TextSegment]): + segments (Sequence[google.cloud.videointelligence_v1.types.TextSegment]): All video segments where OCR detected text appears. version (str): @@ -1259,10 +1259,10 @@ class ObjectTrackingFrame(proto.Message): confidence. Attributes: - normalized_bounding_box (~.video_intelligence.NormalizedBoundingBox): + normalized_bounding_box (google.cloud.videointelligence_v1.types.NormalizedBoundingBox): The normalized bounding box location of this object track for the frame. - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): The timestamp of the frame in microseconds. """ @@ -1277,7 +1277,7 @@ class ObjectTrackingAnnotation(proto.Message): r"""Annotations corresponding to one tracked object. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1.types.VideoSegment): Non-streaming batch mode ONLY. Each object track corresponds to one video segment where it appears. @@ -1288,13 +1288,13 @@ class ObjectTrackingAnnotation(proto.Message): a unique identifiable integer track_id so that the customers can correlate the results of the ongoing ObjectTrackAnnotation of the same track_id over time. - entity (~.video_intelligence.Entity): + entity (google.cloud.videointelligence_v1.types.Entity): Entity to specify the object category that this track is labeled as. confidence (float): Object category's labeling confidence of this track. - frames (Sequence[~.video_intelligence.ObjectTrackingFrame]): + frames (Sequence[google.cloud.videointelligence_v1.types.ObjectTrackingFrame]): Information corresponding to all frames where this object track appears. Non-streaming batch mode: it may be one or multiple @@ -1327,15 +1327,15 @@ class LogoRecognitionAnnotation(proto.Message): recognized logo class. Attributes: - entity (~.video_intelligence.Entity): + entity (google.cloud.videointelligence_v1.types.Entity): Entity category information to specify the logo class that all the logo tracks within this LogoRecognitionAnnotation are recognized as. - tracks (Sequence[~.video_intelligence.Track]): + tracks (Sequence[google.cloud.videointelligence_v1.types.Track]): All logo tracks where the recognized logo appears. Each track corresponds to one logo instance appearing in consecutive frames. - segments (Sequence[~.video_intelligence.VideoSegment]): + segments (Sequence[google.cloud.videointelligence_v1.types.VideoSegment]): All video segments where the recognized logo appears. There might be multiple instances of the same logo class appearing in one diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/async_client.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/async_client.py index 788c95736cd6..1f2e51e0e71d 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/async_client.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/async_client.py @@ -78,7 +78,36 @@ class VideoIntelligenceServiceAsyncClient: VideoIntelligenceServiceClient.parse_common_location_path ) - from_service_account_file = VideoIntelligenceServiceClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceAsyncClient: The constructed client. + """ + return VideoIntelligenceServiceClient.from_service_account_info.__func__(VideoIntelligenceServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceAsyncClient: The constructed client. + """ + return VideoIntelligenceServiceClient.from_service_account_file.__func__(VideoIntelligenceServiceAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property @@ -160,7 +189,7 @@ async def annotate_video( contains ``AnnotateVideoResponse`` (results). Args: - request (:class:`~.video_intelligence.AnnotateVideoRequest`): + request (:class:`google.cloud.videointelligence_v1beta2.types.AnnotateVideoRequest`): The request object. Video annotation request. input_uri (:class:`str`): Input video location. Currently, only `Google Cloud @@ -177,12 +206,14 @@ async def annotate_video( If unset, the input video should be embedded in the request as ``input_content``. If set, ``input_content`` should be unset. + This corresponds to the ``input_uri`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - features (:class:`Sequence[~.video_intelligence.Feature]`): + features (:class:`Sequence[google.cloud.videointelligence_v1beta2.types.Feature]`): Required. Requested video annotation features. + This corresponds to the ``features`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -194,15 +225,12 @@ async def annotate_video( sent along with the request as metadata. Returns: - ~.operation_async.AsyncOperation: + google.api_core.operation_async.AsyncOperation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.video_intelligence.AnnotateVideoResponse``: - Video annotation response. Included in the ``response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.videointelligence_v1beta2.types.AnnotateVideoResponse` Video annotation response. Included in the response + field of the Operation returned by the GetOperation + call of the google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -237,6 +265,7 @@ async def annotate_video( predicate=retries.if_exception_type( exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), + deadline=600.0, ), default_timeout=600.0, client_info=DEFAULT_CLIENT_INFO, diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/client.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/client.py index c8df1586cb70..39bf203ea92a 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/client.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/client.py @@ -113,6 +113,22 @@ def _get_default_mtls_endpoint(api_endpoint): DEFAULT_ENDPOINT ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -125,7 +141,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): kwargs: Additional arguments to pass to the constructor. Returns: - {@api.name}: The constructed client. + VideoIntelligenceServiceClient: The constructed client. """ credentials = service_account.Credentials.from_service_account_file(filename) kwargs["credentials"] = credentials @@ -217,10 +233,10 @@ def __init__( credentials identify the application to the service; if none are specified, the client will attempt to ascertain the credentials from the environment. - transport (Union[str, ~.VideoIntelligenceServiceTransport]): The + transport (Union[str, VideoIntelligenceServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the + client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT @@ -256,21 +272,17 @@ def __init__( util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) ) - ssl_credentials = None + client_cert_source_func = None is_mtls = False if use_client_cert: if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) is_mtls = True + client_cert_source_func = client_options.client_cert_source else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None + is_mtls = mtls.has_default_client_cert_source() + client_cert_source_func = ( + mtls.default_client_cert_source() if is_mtls else None + ) # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -313,7 +325,7 @@ def __init__( credentials_file=client_options.credentials_file, host=api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, ) @@ -335,9 +347,9 @@ def annotate_video( contains ``AnnotateVideoResponse`` (results). Args: - request (:class:`~.video_intelligence.AnnotateVideoRequest`): + request (google.cloud.videointelligence_v1beta2.types.AnnotateVideoRequest): The request object. Video annotation request. - input_uri (:class:`str`): + input_uri (str): Input video location. Currently, only `Google Cloud Storage `__ URIs are supported, which must be specified in the following @@ -352,12 +364,14 @@ def annotate_video( If unset, the input video should be embedded in the request as ``input_content``. If set, ``input_content`` should be unset. + This corresponds to the ``input_uri`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - features (:class:`Sequence[~.video_intelligence.Feature]`): + features (Sequence[google.cloud.videointelligence_v1beta2.types.Feature]): Required. Requested video annotation features. + This corresponds to the ``features`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -369,15 +383,12 @@ def annotate_video( sent along with the request as metadata. Returns: - ~.operation.Operation: + google.api_core.operation.Operation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.video_intelligence.AnnotateVideoResponse``: - Video annotation response. Included in the ``response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.videointelligence_v1beta2.types.AnnotateVideoResponse` Video annotation response. Included in the response + field of the Operation returned by the GetOperation + call of the google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -402,9 +413,8 @@ def annotate_video( if input_uri is not None: request.input_uri = input_uri - - if features: - request.features.extend(features) + if features is not None: + request.features = features # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/base.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/base.py index 3fea249eb44b..f62c9607d4e7 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/base.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/base.py @@ -71,10 +71,10 @@ def __init__( scope (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. """ # Save the hostname. Default to port 443 (HTTPS) if none is specified. @@ -82,6 +82,9 @@ def __init__( host += ":443" self._host = host + # Save the scopes. + self._scopes = scopes or self.AUTH_SCOPES + # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: @@ -91,20 +94,17 @@ def __init__( if credentials_file is not None: credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=scopes, quota_project_id=quota_project_id + credentials_file, scopes=self._scopes, quota_project_id=quota_project_id ) elif credentials is None: credentials, _ = auth.default( - scopes=scopes, quota_project_id=quota_project_id + scopes=self._scopes, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials - # Lifted into its own function so it can be stubbed out during tests. - self._prep_wrapped_messages(client_info) - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -117,6 +117,7 @@ def _prep_wrapped_messages(self, client_info): predicate=retries.if_exception_type( exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), + deadline=600.0, ), default_timeout=600.0, client_info=client_info, diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc.py index b234d58db6e0..5a96ff22c087 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc.py @@ -59,6 +59,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -89,6 +90,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -103,72 +108,61 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -176,18 +170,8 @@ def __init__( ], ) - self._stubs = {} # type: Dict[str, Callable] - self._operations_client = None - - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @classmethod def create_channel( @@ -201,7 +185,7 @@ def create_channel( ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc_asyncio.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc_asyncio.py index 8025381d369d..955e78521164 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc_asyncio.py @@ -63,7 +63,7 @@ def create_channel( ) -> aio.Channel: """Create and return a gRPC AsyncIO channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If @@ -103,6 +103,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -134,12 +135,16 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -148,72 +153,61 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -221,18 +215,8 @@ def __init__( ], ) - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) - - self._stubs = {} - self._operations_client = None + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @property def grpc_channel(self) -> aio.Channel: diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/types/__init__.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/types/__init__.py index 3c4ade04258a..72f210f389f6 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/types/__init__.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/types/__init__.py @@ -16,54 +16,54 @@ # from .video_intelligence import ( + AnnotateVideoProgress, AnnotateVideoRequest, - VideoContext, - LabelDetectionConfig, - ShotChangeDetectionConfig, + AnnotateVideoResponse, + Entity, + ExplicitContentAnnotation, ExplicitContentDetectionConfig, + ExplicitContentFrame, + FaceAnnotation, FaceDetectionConfig, - VideoSegment, - LabelSegment, - LabelFrame, - Entity, + FaceFrame, + FaceSegment, LabelAnnotation, - ExplicitContentFrame, - ExplicitContentAnnotation, + LabelDetectionConfig, + LabelFrame, + LabelSegment, NormalizedBoundingBox, - FaceSegment, - FaceFrame, - FaceAnnotation, - VideoAnnotationResults, - AnnotateVideoResponse, + ShotChangeDetectionConfig, VideoAnnotationProgress, - AnnotateVideoProgress, + VideoAnnotationResults, + VideoContext, + VideoSegment, Feature, LabelDetectionMode, Likelihood, ) __all__ = ( + "AnnotateVideoProgress", "AnnotateVideoRequest", - "VideoContext", - "LabelDetectionConfig", - "ShotChangeDetectionConfig", + "AnnotateVideoResponse", + "Entity", + "ExplicitContentAnnotation", "ExplicitContentDetectionConfig", + "ExplicitContentFrame", + "FaceAnnotation", "FaceDetectionConfig", - "VideoSegment", - "LabelSegment", - "LabelFrame", - "Entity", + "FaceFrame", + "FaceSegment", "LabelAnnotation", - "ExplicitContentFrame", - "ExplicitContentAnnotation", + "LabelDetectionConfig", + "LabelFrame", + "LabelSegment", "NormalizedBoundingBox", - "FaceSegment", - "FaceFrame", - "FaceAnnotation", - "VideoAnnotationResults", - "AnnotateVideoResponse", + "ShotChangeDetectionConfig", "VideoAnnotationProgress", - "AnnotateVideoProgress", + "VideoAnnotationResults", + "VideoContext", + "VideoSegment", "Feature", "LabelDetectionMode", "Likelihood", diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/types/video_intelligence.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/types/video_intelligence.py index 36c0eb656890..1872665a9a17 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/types/video_intelligence.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1beta2/types/video_intelligence.py @@ -103,10 +103,10 @@ class AnnotateVideoRequest(proto.Message): The video data bytes. If unset, the input video(s) should be specified via ``input_uri``. If set, ``input_uri`` should be unset. - features (Sequence[~.video_intelligence.Feature]): + features (Sequence[google.cloud.videointelligence_v1beta2.types.Feature]): Required. Requested video annotation features. - video_context (~.video_intelligence.VideoContext): + video_context (google.cloud.videointelligence_v1beta2.types.VideoContext): Additional video context and/or feature- pecific parameters. output_uri (str): @@ -142,18 +142,18 @@ class VideoContext(proto.Message): r"""Video context and/or feature-specific parameters. Attributes: - segments (Sequence[~.video_intelligence.VideoSegment]): + segments (Sequence[google.cloud.videointelligence_v1beta2.types.VideoSegment]): Video segments to annotate. The segments may overlap and are not required to be contiguous or span the whole video. If unspecified, each video is treated as a single segment. - label_detection_config (~.video_intelligence.LabelDetectionConfig): + label_detection_config (google.cloud.videointelligence_v1beta2.types.LabelDetectionConfig): Config for LABEL_DETECTION. - shot_change_detection_config (~.video_intelligence.ShotChangeDetectionConfig): + shot_change_detection_config (google.cloud.videointelligence_v1beta2.types.ShotChangeDetectionConfig): Config for SHOT_CHANGE_DETECTION. - explicit_content_detection_config (~.video_intelligence.ExplicitContentDetectionConfig): + explicit_content_detection_config (google.cloud.videointelligence_v1beta2.types.ExplicitContentDetectionConfig): Config for EXPLICIT_CONTENT_DETECTION. - face_detection_config (~.video_intelligence.FaceDetectionConfig): + face_detection_config (google.cloud.videointelligence_v1beta2.types.FaceDetectionConfig): Config for FACE_DETECTION. """ @@ -180,7 +180,7 @@ class LabelDetectionConfig(proto.Message): r"""Config for LABEL_DETECTION. Attributes: - label_detection_mode (~.video_intelligence.LabelDetectionMode): + label_detection_mode (google.cloud.videointelligence_v1beta2.types.LabelDetectionMode): What labels should be detected with LABEL_DETECTION, in addition to video-level labels or segment-level labels. If unspecified, defaults to ``SHOT_MODE``. @@ -250,11 +250,11 @@ class VideoSegment(proto.Message): r"""Video segment. Attributes: - start_time_offset (~.duration.Duration): + start_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the start of the segment (inclusive). - end_time_offset (~.duration.Duration): + end_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the end of the segment (inclusive). @@ -269,7 +269,7 @@ class LabelSegment(proto.Message): r"""Video segment level annotation results for label detection. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1beta2.types.VideoSegment): Video segment where a label was detected. confidence (float): Confidence that the label is accurate. Range: [0, 1]. @@ -284,7 +284,7 @@ class LabelFrame(proto.Message): r"""Video frame level annotation results for label detection. Attributes: - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this location. @@ -322,17 +322,17 @@ class LabelAnnotation(proto.Message): r"""Label annotation. Attributes: - entity (~.video_intelligence.Entity): + entity (google.cloud.videointelligence_v1beta2.types.Entity): Detected entity. - category_entities (Sequence[~.video_intelligence.Entity]): + category_entities (Sequence[google.cloud.videointelligence_v1beta2.types.Entity]): Common categories for the detected entity. E.g. when the label is ``Terrier`` the category is likely ``dog``. And in some cases there might be more than one categories e.g. ``Terrier`` could also be a ``pet``. - segments (Sequence[~.video_intelligence.LabelSegment]): + segments (Sequence[google.cloud.videointelligence_v1beta2.types.LabelSegment]): All video segments where a label was detected. - frames (Sequence[~.video_intelligence.LabelFrame]): + frames (Sequence[google.cloud.videointelligence_v1beta2.types.LabelFrame]): All video frames where a label was detected. """ @@ -349,11 +349,11 @@ class ExplicitContentFrame(proto.Message): r"""Video frame level annotation results for explicit content. Attributes: - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this location. - pornography_likelihood (~.video_intelligence.Likelihood): + pornography_likelihood (google.cloud.videointelligence_v1beta2.types.Likelihood): Likelihood of the pornography content.. """ @@ -368,7 +368,7 @@ class ExplicitContentAnnotation(proto.Message): frame, no annotations are present for that frame. Attributes: - frames (Sequence[~.video_intelligence.ExplicitContentFrame]): + frames (Sequence[google.cloud.videointelligence_v1beta2.types.ExplicitContentFrame]): All video frames where explicit content was detected. """ @@ -406,7 +406,7 @@ class FaceSegment(proto.Message): r"""Video segment level annotation results for face detection. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1beta2.types.VideoSegment): Video segment where a face was detected. """ @@ -417,12 +417,12 @@ class FaceFrame(proto.Message): r"""Video frame level annotation results for face detection. Attributes: - normalized_bounding_boxes (Sequence[~.video_intelligence.NormalizedBoundingBox]): + normalized_bounding_boxes (Sequence[google.cloud.videointelligence_v1beta2.types.NormalizedBoundingBox]): Normalized Bounding boxes in a frame. There can be more than one boxes if the same face is detected in multiple locations within the current frame. - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this location. @@ -442,9 +442,9 @@ class FaceAnnotation(proto.Message): thumbnail (bytes): Thumbnail of a representative face view (in JPEG format). - segments (Sequence[~.video_intelligence.FaceSegment]): + segments (Sequence[google.cloud.videointelligence_v1beta2.types.FaceSegment]): All video segments where a face was detected. - frames (Sequence[~.video_intelligence.FaceFrame]): + frames (Sequence[google.cloud.videointelligence_v1beta2.types.FaceFrame]): All video frames where a face was detected. """ @@ -462,27 +462,27 @@ class VideoAnnotationResults(proto.Message): input_uri (str): Video file location in `Google Cloud Storage `__. - segment_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + segment_label_annotations (Sequence[google.cloud.videointelligence_v1beta2.types.LabelAnnotation]): Label annotations on video level or user specified segment level. There is exactly one element for each unique label. - shot_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + shot_label_annotations (Sequence[google.cloud.videointelligence_v1beta2.types.LabelAnnotation]): Label annotations on shot level. There is exactly one element for each unique label. - frame_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + frame_label_annotations (Sequence[google.cloud.videointelligence_v1beta2.types.LabelAnnotation]): Label annotations on frame level. There is exactly one element for each unique label. - face_annotations (Sequence[~.video_intelligence.FaceAnnotation]): + face_annotations (Sequence[google.cloud.videointelligence_v1beta2.types.FaceAnnotation]): Face annotations. There is exactly one element for each unique face. - shot_annotations (Sequence[~.video_intelligence.VideoSegment]): + shot_annotations (Sequence[google.cloud.videointelligence_v1beta2.types.VideoSegment]): Shot annotations. Each shot is represented as a video segment. - explicit_annotation (~.video_intelligence.ExplicitContentAnnotation): + explicit_annotation (google.cloud.videointelligence_v1beta2.types.ExplicitContentAnnotation): Explicit content annotation. - error (~.status.Status): + error (google.rpc.status_pb2.Status): If set, indicates an error. Note that for a single ``AnnotateVideoRequest`` some videos may succeed and some may fail. @@ -523,7 +523,7 @@ class AnnotateVideoResponse(proto.Message): ``google::longrunning::Operations`` service. Attributes: - annotation_results (Sequence[~.video_intelligence.VideoAnnotationResults]): + annotation_results (Sequence[google.cloud.videointelligence_v1beta2.types.VideoAnnotationResults]): Annotation results for all videos specified in ``AnnotateVideoRequest``. """ @@ -543,9 +543,9 @@ class VideoAnnotationProgress(proto.Message): progress_percent (int): Approximate percentage processed thus far. Guaranteed to be 100 when fully processed. - start_time (~.timestamp.Timestamp): + start_time (google.protobuf.timestamp_pb2.Timestamp): Time when the request was received. - update_time (~.timestamp.Timestamp): + update_time (google.protobuf.timestamp_pb2.Timestamp): Time of the most recent update. """ @@ -564,7 +564,7 @@ class AnnotateVideoProgress(proto.Message): ``google::longrunning::Operations`` service. Attributes: - annotation_progress (Sequence[~.video_intelligence.VideoAnnotationProgress]): + annotation_progress (Sequence[google.cloud.videointelligence_v1beta2.types.VideoAnnotationProgress]): Progress metadata for all videos specified in ``AnnotateVideoRequest``. """ diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/async_client.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/async_client.py index b7a986b7f005..37e87175f8b3 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/async_client.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/async_client.py @@ -78,7 +78,36 @@ class VideoIntelligenceServiceAsyncClient: VideoIntelligenceServiceClient.parse_common_location_path ) - from_service_account_file = VideoIntelligenceServiceClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceAsyncClient: The constructed client. + """ + return VideoIntelligenceServiceClient.from_service_account_info.__func__(VideoIntelligenceServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceAsyncClient: The constructed client. + """ + return VideoIntelligenceServiceClient.from_service_account_file.__func__(VideoIntelligenceServiceAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property @@ -160,7 +189,7 @@ async def annotate_video( contains ``AnnotateVideoResponse`` (results). Args: - request (:class:`~.video_intelligence.AnnotateVideoRequest`): + request (:class:`google.cloud.videointelligence_v1p1beta1.types.AnnotateVideoRequest`): The request object. Video annotation request. input_uri (:class:`str`): Input video location. Currently, only `Google Cloud @@ -177,12 +206,14 @@ async def annotate_video( If unset, the input video should be embedded in the request as ``input_content``. If set, ``input_content`` should be unset. + This corresponds to the ``input_uri`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - features (:class:`Sequence[~.video_intelligence.Feature]`): + features (:class:`Sequence[google.cloud.videointelligence_v1p1beta1.types.Feature]`): Required. Requested video annotation features. + This corresponds to the ``features`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -194,15 +225,12 @@ async def annotate_video( sent along with the request as metadata. Returns: - ~.operation_async.AsyncOperation: + google.api_core.operation_async.AsyncOperation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.video_intelligence.AnnotateVideoResponse``: - Video annotation response. Included in the ``response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.videointelligence_v1p1beta1.types.AnnotateVideoResponse` Video annotation response. Included in the response + field of the Operation returned by the GetOperation + call of the google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -237,6 +265,7 @@ async def annotate_video( predicate=retries.if_exception_type( exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), + deadline=600.0, ), default_timeout=600.0, client_info=DEFAULT_CLIENT_INFO, diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/client.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/client.py index ba001598fa48..aa7ee68f91c6 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/client.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/client.py @@ -113,6 +113,22 @@ def _get_default_mtls_endpoint(api_endpoint): DEFAULT_ENDPOINT ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -125,7 +141,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): kwargs: Additional arguments to pass to the constructor. Returns: - {@api.name}: The constructed client. + VideoIntelligenceServiceClient: The constructed client. """ credentials = service_account.Credentials.from_service_account_file(filename) kwargs["credentials"] = credentials @@ -217,10 +233,10 @@ def __init__( credentials identify the application to the service; if none are specified, the client will attempt to ascertain the credentials from the environment. - transport (Union[str, ~.VideoIntelligenceServiceTransport]): The + transport (Union[str, VideoIntelligenceServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the + client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT @@ -256,21 +272,17 @@ def __init__( util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) ) - ssl_credentials = None + client_cert_source_func = None is_mtls = False if use_client_cert: if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) is_mtls = True + client_cert_source_func = client_options.client_cert_source else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None + is_mtls = mtls.has_default_client_cert_source() + client_cert_source_func = ( + mtls.default_client_cert_source() if is_mtls else None + ) # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -313,7 +325,7 @@ def __init__( credentials_file=client_options.credentials_file, host=api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, ) @@ -335,9 +347,9 @@ def annotate_video( contains ``AnnotateVideoResponse`` (results). Args: - request (:class:`~.video_intelligence.AnnotateVideoRequest`): + request (google.cloud.videointelligence_v1p1beta1.types.AnnotateVideoRequest): The request object. Video annotation request. - input_uri (:class:`str`): + input_uri (str): Input video location. Currently, only `Google Cloud Storage `__ URIs are supported, which must be specified in the following @@ -352,12 +364,14 @@ def annotate_video( If unset, the input video should be embedded in the request as ``input_content``. If set, ``input_content`` should be unset. + This corresponds to the ``input_uri`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - features (:class:`Sequence[~.video_intelligence.Feature]`): + features (Sequence[google.cloud.videointelligence_v1p1beta1.types.Feature]): Required. Requested video annotation features. + This corresponds to the ``features`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -369,15 +383,12 @@ def annotate_video( sent along with the request as metadata. Returns: - ~.operation.Operation: + google.api_core.operation.Operation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.video_intelligence.AnnotateVideoResponse``: - Video annotation response. Included in the ``response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.videointelligence_v1p1beta1.types.AnnotateVideoResponse` Video annotation response. Included in the response + field of the Operation returned by the GetOperation + call of the google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -402,9 +413,8 @@ def annotate_video( if input_uri is not None: request.input_uri = input_uri - - if features: - request.features.extend(features) + if features is not None: + request.features = features # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/base.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/base.py index 0117c0f9ff14..95339b8e38ba 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/base.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/base.py @@ -71,10 +71,10 @@ def __init__( scope (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. """ # Save the hostname. Default to port 443 (HTTPS) if none is specified. @@ -82,6 +82,9 @@ def __init__( host += ":443" self._host = host + # Save the scopes. + self._scopes = scopes or self.AUTH_SCOPES + # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: @@ -91,20 +94,17 @@ def __init__( if credentials_file is not None: credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=scopes, quota_project_id=quota_project_id + credentials_file, scopes=self._scopes, quota_project_id=quota_project_id ) elif credentials is None: credentials, _ = auth.default( - scopes=scopes, quota_project_id=quota_project_id + scopes=self._scopes, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials - # Lifted into its own function so it can be stubbed out during tests. - self._prep_wrapped_messages(client_info) - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -117,6 +117,7 @@ def _prep_wrapped_messages(self, client_info): predicate=retries.if_exception_type( exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), + deadline=600.0, ), default_timeout=600.0, client_info=client_info, diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc.py index 812ca5f435af..3a036a9c054e 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc.py @@ -59,6 +59,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -89,6 +90,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -103,72 +108,61 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -176,18 +170,8 @@ def __init__( ], ) - self._stubs = {} # type: Dict[str, Callable] - self._operations_client = None - - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @classmethod def create_channel( @@ -201,7 +185,7 @@ def create_channel( ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc_asyncio.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc_asyncio.py index 86b24ef4a00c..ef3631aa05b7 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc_asyncio.py @@ -63,7 +63,7 @@ def create_channel( ) -> aio.Channel: """Create and return a gRPC AsyncIO channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If @@ -103,6 +103,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -134,12 +135,16 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -148,72 +153,61 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -221,18 +215,8 @@ def __init__( ], ) - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) - - self._stubs = {} - self._operations_client = None + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @property def grpc_channel(self) -> aio.Channel: diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/types/__init__.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/types/__init__.py index d13e015a41b5..8e9d34af56d4 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/types/__init__.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/types/__init__.py @@ -16,26 +16,26 @@ # from .video_intelligence import ( + AnnotateVideoProgress, AnnotateVideoRequest, - VideoContext, - LabelDetectionConfig, - ShotChangeDetectionConfig, - ExplicitContentDetectionConfig, - VideoSegment, - LabelSegment, - LabelFrame, + AnnotateVideoResponse, Entity, - LabelAnnotation, - ExplicitContentFrame, ExplicitContentAnnotation, - VideoAnnotationResults, - AnnotateVideoResponse, - VideoAnnotationProgress, - AnnotateVideoProgress, - SpeechTranscriptionConfig, + ExplicitContentDetectionConfig, + ExplicitContentFrame, + LabelAnnotation, + LabelDetectionConfig, + LabelFrame, + LabelSegment, + ShotChangeDetectionConfig, SpeechContext, - SpeechTranscription, SpeechRecognitionAlternative, + SpeechTranscription, + SpeechTranscriptionConfig, + VideoAnnotationProgress, + VideoAnnotationResults, + VideoContext, + VideoSegment, WordInfo, Feature, LabelDetectionMode, @@ -43,26 +43,26 @@ ) __all__ = ( + "AnnotateVideoProgress", "AnnotateVideoRequest", - "VideoContext", - "LabelDetectionConfig", - "ShotChangeDetectionConfig", - "ExplicitContentDetectionConfig", - "VideoSegment", - "LabelSegment", - "LabelFrame", + "AnnotateVideoResponse", "Entity", - "LabelAnnotation", - "ExplicitContentFrame", "ExplicitContentAnnotation", - "VideoAnnotationResults", - "AnnotateVideoResponse", - "VideoAnnotationProgress", - "AnnotateVideoProgress", - "SpeechTranscriptionConfig", + "ExplicitContentDetectionConfig", + "ExplicitContentFrame", + "LabelAnnotation", + "LabelDetectionConfig", + "LabelFrame", + "LabelSegment", + "ShotChangeDetectionConfig", "SpeechContext", - "SpeechTranscription", "SpeechRecognitionAlternative", + "SpeechTranscription", + "SpeechTranscriptionConfig", + "VideoAnnotationProgress", + "VideoAnnotationResults", + "VideoContext", + "VideoSegment", "WordInfo", "Feature", "LabelDetectionMode", diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/types/video_intelligence.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/types/video_intelligence.py index c766ccc87594..4f7cf766dc30 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/types/video_intelligence.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p1beta1/types/video_intelligence.py @@ -103,10 +103,10 @@ class AnnotateVideoRequest(proto.Message): The video data bytes. If unset, the input video(s) should be specified via ``input_uri``. If set, ``input_uri`` should be unset. - features (Sequence[~.video_intelligence.Feature]): + features (Sequence[google.cloud.videointelligence_v1p1beta1.types.Feature]): Required. Requested video annotation features. - video_context (~.video_intelligence.VideoContext): + video_context (google.cloud.videointelligence_v1p1beta1.types.VideoContext): Additional video context and/or feature- pecific parameters. output_uri (str): @@ -142,18 +142,18 @@ class VideoContext(proto.Message): r"""Video context and/or feature-specific parameters. Attributes: - segments (Sequence[~.video_intelligence.VideoSegment]): + segments (Sequence[google.cloud.videointelligence_v1p1beta1.types.VideoSegment]): Video segments to annotate. The segments may overlap and are not required to be contiguous or span the whole video. If unspecified, each video is treated as a single segment. - label_detection_config (~.video_intelligence.LabelDetectionConfig): + label_detection_config (google.cloud.videointelligence_v1p1beta1.types.LabelDetectionConfig): Config for LABEL_DETECTION. - shot_change_detection_config (~.video_intelligence.ShotChangeDetectionConfig): + shot_change_detection_config (google.cloud.videointelligence_v1p1beta1.types.ShotChangeDetectionConfig): Config for SHOT_CHANGE_DETECTION. - explicit_content_detection_config (~.video_intelligence.ExplicitContentDetectionConfig): + explicit_content_detection_config (google.cloud.videointelligence_v1p1beta1.types.ExplicitContentDetectionConfig): Config for EXPLICIT_CONTENT_DETECTION. - speech_transcription_config (~.video_intelligence.SpeechTranscriptionConfig): + speech_transcription_config (google.cloud.videointelligence_v1p1beta1.types.SpeechTranscriptionConfig): Config for SPEECH_TRANSCRIPTION. """ @@ -180,7 +180,7 @@ class LabelDetectionConfig(proto.Message): r"""Config for LABEL_DETECTION. Attributes: - label_detection_mode (~.video_intelligence.LabelDetectionMode): + label_detection_mode (google.cloud.videointelligence_v1p1beta1.types.LabelDetectionMode): What labels should be detected with LABEL_DETECTION, in addition to video-level labels or segment-level labels. If unspecified, defaults to ``SHOT_MODE``. @@ -232,11 +232,11 @@ class VideoSegment(proto.Message): r"""Video segment. Attributes: - start_time_offset (~.duration.Duration): + start_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the start of the segment (inclusive). - end_time_offset (~.duration.Duration): + end_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the end of the segment (inclusive). @@ -251,7 +251,7 @@ class LabelSegment(proto.Message): r"""Video segment level annotation results for label detection. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1p1beta1.types.VideoSegment): Video segment where a label was detected. confidence (float): Confidence that the label is accurate. Range: [0, 1]. @@ -266,7 +266,7 @@ class LabelFrame(proto.Message): r"""Video frame level annotation results for label detection. Attributes: - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this location. @@ -304,17 +304,17 @@ class LabelAnnotation(proto.Message): r"""Label annotation. Attributes: - entity (~.video_intelligence.Entity): + entity (google.cloud.videointelligence_v1p1beta1.types.Entity): Detected entity. - category_entities (Sequence[~.video_intelligence.Entity]): + category_entities (Sequence[google.cloud.videointelligence_v1p1beta1.types.Entity]): Common categories for the detected entity. E.g. when the label is ``Terrier`` the category is likely ``dog``. And in some cases there might be more than one categories e.g. ``Terrier`` could also be a ``pet``. - segments (Sequence[~.video_intelligence.LabelSegment]): + segments (Sequence[google.cloud.videointelligence_v1p1beta1.types.LabelSegment]): All video segments where a label was detected. - frames (Sequence[~.video_intelligence.LabelFrame]): + frames (Sequence[google.cloud.videointelligence_v1p1beta1.types.LabelFrame]): All video frames where a label was detected. """ @@ -331,11 +331,11 @@ class ExplicitContentFrame(proto.Message): r"""Video frame level annotation results for explicit content. Attributes: - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this location. - pornography_likelihood (~.video_intelligence.Likelihood): + pornography_likelihood (google.cloud.videointelligence_v1p1beta1.types.Likelihood): Likelihood of the pornography content.. """ @@ -350,7 +350,7 @@ class ExplicitContentAnnotation(proto.Message): frame, no annotations are present for that frame. Attributes: - frames (Sequence[~.video_intelligence.ExplicitContentFrame]): + frames (Sequence[google.cloud.videointelligence_v1p1beta1.types.ExplicitContentFrame]): All video frames where explicit content was detected. """ @@ -367,26 +367,26 @@ class VideoAnnotationResults(proto.Message): input_uri (str): Output only. Video file location in `Google Cloud Storage `__. - segment_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + segment_label_annotations (Sequence[google.cloud.videointelligence_v1p1beta1.types.LabelAnnotation]): Label annotations on video level or user specified segment level. There is exactly one element for each unique label. - shot_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + shot_label_annotations (Sequence[google.cloud.videointelligence_v1p1beta1.types.LabelAnnotation]): Label annotations on shot level. There is exactly one element for each unique label. - frame_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + frame_label_annotations (Sequence[google.cloud.videointelligence_v1p1beta1.types.LabelAnnotation]): Label annotations on frame level. There is exactly one element for each unique label. - shot_annotations (Sequence[~.video_intelligence.VideoSegment]): + shot_annotations (Sequence[google.cloud.videointelligence_v1p1beta1.types.VideoSegment]): Shot annotations. Each shot is represented as a video segment. - explicit_annotation (~.video_intelligence.ExplicitContentAnnotation): + explicit_annotation (google.cloud.videointelligence_v1p1beta1.types.ExplicitContentAnnotation): Explicit content annotation. - speech_transcriptions (Sequence[~.video_intelligence.SpeechTranscription]): + speech_transcriptions (Sequence[google.cloud.videointelligence_v1p1beta1.types.SpeechTranscription]): Speech transcription. - error (~.status.Status): + error (google.rpc.status_pb2.Status): Output only. If set, indicates an error. Note that for a single ``AnnotateVideoRequest`` some videos may succeed and some may fail. @@ -427,7 +427,7 @@ class AnnotateVideoResponse(proto.Message): ``google::longrunning::Operations`` service. Attributes: - annotation_results (Sequence[~.video_intelligence.VideoAnnotationResults]): + annotation_results (Sequence[google.cloud.videointelligence_v1p1beta1.types.VideoAnnotationResults]): Annotation results for all videos specified in ``AnnotateVideoRequest``. """ @@ -448,10 +448,10 @@ class VideoAnnotationProgress(proto.Message): Output only. Approximate percentage processed thus far. Guaranteed to be 100 when fully processed. - start_time (~.timestamp.Timestamp): + start_time (google.protobuf.timestamp_pb2.Timestamp): Output only. Time when the request was received. - update_time (~.timestamp.Timestamp): + update_time (google.protobuf.timestamp_pb2.Timestamp): Output only. Time of the most recent update. """ @@ -470,7 +470,7 @@ class AnnotateVideoProgress(proto.Message): ``google::longrunning::Operations`` service. Attributes: - annotation_progress (Sequence[~.video_intelligence.VideoAnnotationProgress]): + annotation_progress (Sequence[google.cloud.videointelligence_v1p1beta1.types.VideoAnnotationProgress]): Progress metadata for all videos specified in ``AnnotateVideoRequest``. """ @@ -504,7 +504,7 @@ class SpeechTranscriptionConfig(proto.Message): character in each filtered word with asterisks, e.g. "f***". If set to ``false`` or omitted, profanities won't be filtered out. - speech_contexts (Sequence[~.video_intelligence.SpeechContext]): + speech_contexts (Sequence[google.cloud.videointelligence_v1p1beta1.types.SpeechContext]): Optional. A means to provide context to assist the speech recognition. enable_automatic_punctuation (bool): @@ -563,7 +563,7 @@ class SpeechTranscription(proto.Message): audio. Attributes: - alternatives (Sequence[~.video_intelligence.SpeechRecognitionAlternative]): + alternatives (Sequence[google.cloud.videointelligence_v1p1beta1.types.SpeechRecognitionAlternative]): May contain one or more recognition hypotheses (up to the maximum specified in ``max_alternatives``). These alternatives are ordered in terms of accuracy, with the top @@ -591,7 +591,7 @@ class SpeechRecognitionAlternative(proto.Message): accurate and users should not rely on it to be always provided. The default of 0.0 is a sentinel value indicating ``confidence`` was not set. - words (Sequence[~.video_intelligence.WordInfo]): + words (Sequence[google.cloud.videointelligence_v1p1beta1.types.WordInfo]): Output only. A list of word-specific information for each recognized word. """ @@ -609,13 +609,13 @@ class WordInfo(proto.Message): set, such as ``enable_word_time_offsets``. Attributes: - start_time (~.duration.Duration): + start_time (google.protobuf.duration_pb2.Duration): Output only. Time offset relative to the beginning of the audio, and corresponding to the start of the spoken word. This field is only set if ``enable_word_time_offsets=true`` and only in the top hypothesis. This is an experimental feature and the accuracy of the time offset can vary. - end_time (~.duration.Duration): + end_time (google.protobuf.duration_pb2.Duration): Output only. Time offset relative to the beginning of the audio, and corresponding to the end of the spoken word. This field is only set if ``enable_word_time_offsets=true`` and diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/async_client.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/async_client.py index d62d470bde6e..ac3f4fda8dff 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/async_client.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/async_client.py @@ -78,7 +78,36 @@ class VideoIntelligenceServiceAsyncClient: VideoIntelligenceServiceClient.parse_common_location_path ) - from_service_account_file = VideoIntelligenceServiceClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceAsyncClient: The constructed client. + """ + return VideoIntelligenceServiceClient.from_service_account_info.__func__(VideoIntelligenceServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceAsyncClient: The constructed client. + """ + return VideoIntelligenceServiceClient.from_service_account_file.__func__(VideoIntelligenceServiceAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property @@ -160,7 +189,7 @@ async def annotate_video( contains ``AnnotateVideoResponse`` (results). Args: - request (:class:`~.video_intelligence.AnnotateVideoRequest`): + request (:class:`google.cloud.videointelligence_v1p2beta1.types.AnnotateVideoRequest`): The request object. Video annotation request. input_uri (:class:`str`): Input video location. Currently, only `Google Cloud @@ -177,12 +206,14 @@ async def annotate_video( If unset, the input video should be embedded in the request as ``input_content``. If set, ``input_content`` should be unset. + This corresponds to the ``input_uri`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - features (:class:`Sequence[~.video_intelligence.Feature]`): + features (:class:`Sequence[google.cloud.videointelligence_v1p2beta1.types.Feature]`): Required. Requested video annotation features. + This corresponds to the ``features`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -194,15 +225,12 @@ async def annotate_video( sent along with the request as metadata. Returns: - ~.operation_async.AsyncOperation: + google.api_core.operation_async.AsyncOperation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.video_intelligence.AnnotateVideoResponse``: - Video annotation response. Included in the ``response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.videointelligence_v1p2beta1.types.AnnotateVideoResponse` Video annotation response. Included in the response + field of the Operation returned by the GetOperation + call of the google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -237,6 +265,7 @@ async def annotate_video( predicate=retries.if_exception_type( exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), + deadline=600.0, ), default_timeout=600.0, client_info=DEFAULT_CLIENT_INFO, diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/client.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/client.py index 4034262bd914..1e1b9dd9b1e4 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/client.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/client.py @@ -113,6 +113,22 @@ def _get_default_mtls_endpoint(api_endpoint): DEFAULT_ENDPOINT ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -125,7 +141,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): kwargs: Additional arguments to pass to the constructor. Returns: - {@api.name}: The constructed client. + VideoIntelligenceServiceClient: The constructed client. """ credentials = service_account.Credentials.from_service_account_file(filename) kwargs["credentials"] = credentials @@ -217,10 +233,10 @@ def __init__( credentials identify the application to the service; if none are specified, the client will attempt to ascertain the credentials from the environment. - transport (Union[str, ~.VideoIntelligenceServiceTransport]): The + transport (Union[str, VideoIntelligenceServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the + client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT @@ -256,21 +272,17 @@ def __init__( util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) ) - ssl_credentials = None + client_cert_source_func = None is_mtls = False if use_client_cert: if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) is_mtls = True + client_cert_source_func = client_options.client_cert_source else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None + is_mtls = mtls.has_default_client_cert_source() + client_cert_source_func = ( + mtls.default_client_cert_source() if is_mtls else None + ) # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -313,7 +325,7 @@ def __init__( credentials_file=client_options.credentials_file, host=api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, ) @@ -335,9 +347,9 @@ def annotate_video( contains ``AnnotateVideoResponse`` (results). Args: - request (:class:`~.video_intelligence.AnnotateVideoRequest`): + request (google.cloud.videointelligence_v1p2beta1.types.AnnotateVideoRequest): The request object. Video annotation request. - input_uri (:class:`str`): + input_uri (str): Input video location. Currently, only `Google Cloud Storage `__ URIs are supported, which must be specified in the following @@ -352,12 +364,14 @@ def annotate_video( If unset, the input video should be embedded in the request as ``input_content``. If set, ``input_content`` should be unset. + This corresponds to the ``input_uri`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - features (:class:`Sequence[~.video_intelligence.Feature]`): + features (Sequence[google.cloud.videointelligence_v1p2beta1.types.Feature]): Required. Requested video annotation features. + This corresponds to the ``features`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -369,15 +383,12 @@ def annotate_video( sent along with the request as metadata. Returns: - ~.operation.Operation: + google.api_core.operation.Operation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.video_intelligence.AnnotateVideoResponse``: - Video annotation response. Included in the ``response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.videointelligence_v1p2beta1.types.AnnotateVideoResponse` Video annotation response. Included in the response + field of the Operation returned by the GetOperation + call of the google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -402,9 +413,8 @@ def annotate_video( if input_uri is not None: request.input_uri = input_uri - - if features: - request.features.extend(features) + if features is not None: + request.features = features # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/base.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/base.py index 774e7752750c..dc1d2ddcb330 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/base.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/base.py @@ -71,10 +71,10 @@ def __init__( scope (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. """ # Save the hostname. Default to port 443 (HTTPS) if none is specified. @@ -82,6 +82,9 @@ def __init__( host += ":443" self._host = host + # Save the scopes. + self._scopes = scopes or self.AUTH_SCOPES + # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: @@ -91,20 +94,17 @@ def __init__( if credentials_file is not None: credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=scopes, quota_project_id=quota_project_id + credentials_file, scopes=self._scopes, quota_project_id=quota_project_id ) elif credentials is None: credentials, _ = auth.default( - scopes=scopes, quota_project_id=quota_project_id + scopes=self._scopes, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials - # Lifted into its own function so it can be stubbed out during tests. - self._prep_wrapped_messages(client_info) - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -117,6 +117,7 @@ def _prep_wrapped_messages(self, client_info): predicate=retries.if_exception_type( exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), + deadline=600.0, ), default_timeout=600.0, client_info=client_info, diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc.py index 7c5994076f4a..a41cccee4f07 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc.py @@ -59,6 +59,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -89,6 +90,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -103,72 +108,61 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -176,18 +170,8 @@ def __init__( ], ) - self._stubs = {} # type: Dict[str, Callable] - self._operations_client = None - - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @classmethod def create_channel( @@ -201,7 +185,7 @@ def create_channel( ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc_asyncio.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc_asyncio.py index db30a3df31bc..4daff5eca25e 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc_asyncio.py @@ -63,7 +63,7 @@ def create_channel( ) -> aio.Channel: """Create and return a gRPC AsyncIO channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If @@ -103,6 +103,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -134,12 +135,16 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -148,72 +153,61 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -221,18 +215,8 @@ def __init__( ], ) - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) - - self._stubs = {} - self._operations_client = None + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @property def grpc_channel(self) -> aio.Channel: diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/types/__init__.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/types/__init__.py index 3b7bf4c235b5..fc0e4966782c 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/types/__init__.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/types/__init__.py @@ -16,62 +16,62 @@ # from .video_intelligence import ( + AnnotateVideoProgress, AnnotateVideoRequest, - VideoContext, - LabelDetectionConfig, - ShotChangeDetectionConfig, - ExplicitContentDetectionConfig, - TextDetectionConfig, - VideoSegment, - LabelSegment, - LabelFrame, + AnnotateVideoResponse, Entity, - LabelAnnotation, - ExplicitContentFrame, ExplicitContentAnnotation, + ExplicitContentDetectionConfig, + ExplicitContentFrame, + LabelAnnotation, + LabelDetectionConfig, + LabelFrame, + LabelSegment, NormalizedBoundingBox, - VideoAnnotationResults, - AnnotateVideoResponse, - VideoAnnotationProgress, - AnnotateVideoProgress, - NormalizedVertex, NormalizedBoundingPoly, - TextSegment, - TextFrame, - TextAnnotation, - ObjectTrackingFrame, + NormalizedVertex, ObjectTrackingAnnotation, + ObjectTrackingFrame, + ShotChangeDetectionConfig, + TextAnnotation, + TextDetectionConfig, + TextFrame, + TextSegment, + VideoAnnotationProgress, + VideoAnnotationResults, + VideoContext, + VideoSegment, Feature, LabelDetectionMode, Likelihood, ) __all__ = ( + "AnnotateVideoProgress", "AnnotateVideoRequest", - "VideoContext", - "LabelDetectionConfig", - "ShotChangeDetectionConfig", - "ExplicitContentDetectionConfig", - "TextDetectionConfig", - "VideoSegment", - "LabelSegment", - "LabelFrame", + "AnnotateVideoResponse", "Entity", - "LabelAnnotation", - "ExplicitContentFrame", "ExplicitContentAnnotation", + "ExplicitContentDetectionConfig", + "ExplicitContentFrame", + "LabelAnnotation", + "LabelDetectionConfig", + "LabelFrame", + "LabelSegment", "NormalizedBoundingBox", - "VideoAnnotationResults", - "AnnotateVideoResponse", - "VideoAnnotationProgress", - "AnnotateVideoProgress", - "NormalizedVertex", "NormalizedBoundingPoly", - "TextSegment", - "TextFrame", - "TextAnnotation", - "ObjectTrackingFrame", + "NormalizedVertex", "ObjectTrackingAnnotation", + "ObjectTrackingFrame", + "ShotChangeDetectionConfig", + "TextAnnotation", + "TextDetectionConfig", + "TextFrame", + "TextSegment", + "VideoAnnotationProgress", + "VideoAnnotationResults", + "VideoContext", + "VideoSegment", "Feature", "LabelDetectionMode", "Likelihood", diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/types/video_intelligence.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/types/video_intelligence.py index 2f533ed86796..62df5db7ccb2 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/types/video_intelligence.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p2beta1/types/video_intelligence.py @@ -108,10 +108,10 @@ class AnnotateVideoRequest(proto.Message): The video data bytes. If unset, the input video(s) should be specified via ``input_uri``. If set, ``input_uri`` should be unset. - features (Sequence[~.video_intelligence.Feature]): + features (Sequence[google.cloud.videointelligence_v1p2beta1.types.Feature]): Required. Requested video annotation features. - video_context (~.video_intelligence.VideoContext): + video_context (google.cloud.videointelligence_v1p2beta1.types.VideoContext): Additional video context and/or feature- pecific parameters. output_uri (str): @@ -147,18 +147,18 @@ class VideoContext(proto.Message): r"""Video context and/or feature-specific parameters. Attributes: - segments (Sequence[~.video_intelligence.VideoSegment]): + segments (Sequence[google.cloud.videointelligence_v1p2beta1.types.VideoSegment]): Video segments to annotate. The segments may overlap and are not required to be contiguous or span the whole video. If unspecified, each video is treated as a single segment. - label_detection_config (~.video_intelligence.LabelDetectionConfig): + label_detection_config (google.cloud.videointelligence_v1p2beta1.types.LabelDetectionConfig): Config for LABEL_DETECTION. - shot_change_detection_config (~.video_intelligence.ShotChangeDetectionConfig): + shot_change_detection_config (google.cloud.videointelligence_v1p2beta1.types.ShotChangeDetectionConfig): Config for SHOT_CHANGE_DETECTION. - explicit_content_detection_config (~.video_intelligence.ExplicitContentDetectionConfig): + explicit_content_detection_config (google.cloud.videointelligence_v1p2beta1.types.ExplicitContentDetectionConfig): Config for EXPLICIT_CONTENT_DETECTION. - text_detection_config (~.video_intelligence.TextDetectionConfig): + text_detection_config (google.cloud.videointelligence_v1p2beta1.types.TextDetectionConfig): Config for TEXT_DETECTION. """ @@ -185,7 +185,7 @@ class LabelDetectionConfig(proto.Message): r"""Config for LABEL_DETECTION. Attributes: - label_detection_mode (~.video_intelligence.LabelDetectionMode): + label_detection_mode (google.cloud.videointelligence_v1p2beta1.types.LabelDetectionMode): What labels should be detected with LABEL_DETECTION, in addition to video-level labels or segment-level labels. If unspecified, defaults to ``SHOT_MODE``. @@ -255,11 +255,11 @@ class VideoSegment(proto.Message): r"""Video segment. Attributes: - start_time_offset (~.duration.Duration): + start_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the start of the segment (inclusive). - end_time_offset (~.duration.Duration): + end_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the end of the segment (inclusive). @@ -274,7 +274,7 @@ class LabelSegment(proto.Message): r"""Video segment level annotation results for label detection. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1p2beta1.types.VideoSegment): Video segment where a label was detected. confidence (float): Confidence that the label is accurate. Range: [0, 1]. @@ -289,7 +289,7 @@ class LabelFrame(proto.Message): r"""Video frame level annotation results for label detection. Attributes: - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this location. @@ -327,17 +327,17 @@ class LabelAnnotation(proto.Message): r"""Label annotation. Attributes: - entity (~.video_intelligence.Entity): + entity (google.cloud.videointelligence_v1p2beta1.types.Entity): Detected entity. - category_entities (Sequence[~.video_intelligence.Entity]): + category_entities (Sequence[google.cloud.videointelligence_v1p2beta1.types.Entity]): Common categories for the detected entity. E.g. when the label is ``Terrier`` the category is likely ``dog``. And in some cases there might be more than one categories e.g. ``Terrier`` could also be a ``pet``. - segments (Sequence[~.video_intelligence.LabelSegment]): + segments (Sequence[google.cloud.videointelligence_v1p2beta1.types.LabelSegment]): All video segments where a label was detected. - frames (Sequence[~.video_intelligence.LabelFrame]): + frames (Sequence[google.cloud.videointelligence_v1p2beta1.types.LabelFrame]): All video frames where a label was detected. """ @@ -354,11 +354,11 @@ class ExplicitContentFrame(proto.Message): r"""Video frame level annotation results for explicit content. Attributes: - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this location. - pornography_likelihood (~.video_intelligence.Likelihood): + pornography_likelihood (google.cloud.videointelligence_v1p2beta1.types.Likelihood): Likelihood of the pornography content.. """ @@ -373,7 +373,7 @@ class ExplicitContentAnnotation(proto.Message): frame, no annotations are present for that frame. Attributes: - frames (Sequence[~.video_intelligence.ExplicitContentFrame]): + frames (Sequence[google.cloud.videointelligence_v1p2beta1.types.ExplicitContentFrame]): All video frames where explicit content was detected. """ @@ -414,32 +414,32 @@ class VideoAnnotationResults(proto.Message): input_uri (str): Video file location in `Google Cloud Storage `__. - segment_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + segment_label_annotations (Sequence[google.cloud.videointelligence_v1p2beta1.types.LabelAnnotation]): Label annotations on video level or user specified segment level. There is exactly one element for each unique label. - shot_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + shot_label_annotations (Sequence[google.cloud.videointelligence_v1p2beta1.types.LabelAnnotation]): Label annotations on shot level. There is exactly one element for each unique label. - frame_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + frame_label_annotations (Sequence[google.cloud.videointelligence_v1p2beta1.types.LabelAnnotation]): Label annotations on frame level. There is exactly one element for each unique label. - shot_annotations (Sequence[~.video_intelligence.VideoSegment]): + shot_annotations (Sequence[google.cloud.videointelligence_v1p2beta1.types.VideoSegment]): Shot annotations. Each shot is represented as a video segment. - explicit_annotation (~.video_intelligence.ExplicitContentAnnotation): + explicit_annotation (google.cloud.videointelligence_v1p2beta1.types.ExplicitContentAnnotation): Explicit content annotation. - text_annotations (Sequence[~.video_intelligence.TextAnnotation]): + text_annotations (Sequence[google.cloud.videointelligence_v1p2beta1.types.TextAnnotation]): OCR text detection and tracking. Annotations for list of detected text snippets. Each will have list of frame information associated with it. - object_annotations (Sequence[~.video_intelligence.ObjectTrackingAnnotation]): + object_annotations (Sequence[google.cloud.videointelligence_v1p2beta1.types.ObjectTrackingAnnotation]): Annotations for list of objects detected and tracked in video. - error (~.status.Status): + error (google.rpc.status_pb2.Status): If set, indicates an error. Note that for a single ``AnnotateVideoRequest`` some videos may succeed and some may fail. @@ -484,7 +484,7 @@ class AnnotateVideoResponse(proto.Message): ``google::longrunning::Operations`` service. Attributes: - annotation_results (Sequence[~.video_intelligence.VideoAnnotationResults]): + annotation_results (Sequence[google.cloud.videointelligence_v1p2beta1.types.VideoAnnotationResults]): Annotation results for all videos specified in ``AnnotateVideoRequest``. """ @@ -504,9 +504,9 @@ class VideoAnnotationProgress(proto.Message): progress_percent (int): Approximate percentage processed thus far. Guaranteed to be 100 when fully processed. - start_time (~.timestamp.Timestamp): + start_time (google.protobuf.timestamp_pb2.Timestamp): Time when the request was received. - update_time (~.timestamp.Timestamp): + update_time (google.protobuf.timestamp_pb2.Timestamp): Time of the most recent update. """ @@ -525,7 +525,7 @@ class AnnotateVideoProgress(proto.Message): ``google::longrunning::Operations`` service. Attributes: - annotation_progress (Sequence[~.video_intelligence.VideoAnnotationProgress]): + annotation_progress (Sequence[google.cloud.videointelligence_v1p2beta1.types.VideoAnnotationProgress]): Progress metadata for all videos specified in ``AnnotateVideoRequest``. """ @@ -567,7 +567,7 @@ class NormalizedBoundingPoly(proto.Message): calculations for location of the box. Attributes: - vertices (Sequence[~.video_intelligence.NormalizedVertex]): + vertices (Sequence[google.cloud.videointelligence_v1p2beta1.types.NormalizedVertex]): Normalized vertices of the bounding polygon. """ @@ -578,14 +578,14 @@ class TextSegment(proto.Message): r"""Video segment level annotation results for text detection. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1p2beta1.types.VideoSegment): Video segment where a text snippet was detected. confidence (float): Confidence for the track of detected text. It is calculated as the highest over all frames where OCR detected text appears. - frames (Sequence[~.video_intelligence.TextFrame]): + frames (Sequence[google.cloud.videointelligence_v1p2beta1.types.TextFrame]): Information related to the frames where OCR detected text appears. """ @@ -603,10 +603,10 @@ class TextFrame(proto.Message): locations for the frames containing detected OCR text snippets. Attributes: - rotated_bounding_box (~.video_intelligence.NormalizedBoundingPoly): + rotated_bounding_box (google.cloud.videointelligence_v1p2beta1.types.NormalizedBoundingPoly): Bounding polygon of the detected text for this frame. - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Timestamp of this frame. """ @@ -625,7 +625,7 @@ class TextAnnotation(proto.Message): Attributes: text (str): The detected text. - segments (Sequence[~.video_intelligence.TextSegment]): + segments (Sequence[google.cloud.videointelligence_v1p2beta1.types.TextSegment]): All video segments where OCR detected text appears. """ @@ -641,10 +641,10 @@ class ObjectTrackingFrame(proto.Message): confidence. Attributes: - normalized_bounding_box (~.video_intelligence.NormalizedBoundingBox): + normalized_bounding_box (google.cloud.videointelligence_v1p2beta1.types.NormalizedBoundingBox): The normalized bounding box location of this object track for the frame. - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): The timestamp of the frame in microseconds. """ @@ -659,16 +659,16 @@ class ObjectTrackingAnnotation(proto.Message): r"""Annotations corresponding to one tracked object. Attributes: - entity (~.video_intelligence.Entity): + entity (google.cloud.videointelligence_v1p2beta1.types.Entity): Entity to specify the object category that this track is labeled as. confidence (float): Object category's labeling confidence of this track. - frames (Sequence[~.video_intelligence.ObjectTrackingFrame]): + frames (Sequence[google.cloud.videointelligence_v1p2beta1.types.ObjectTrackingFrame]): Information corresponding to all frames where this object track appears. - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1p2beta1.types.VideoSegment): Each object track corresponds to one video segment where it appears. """ diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/async_client.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/async_client.py index f5b04c1965ac..dd530073a355 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/async_client.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/async_client.py @@ -95,9 +95,36 @@ class StreamingVideoIntelligenceServiceAsyncClient: StreamingVideoIntelligenceServiceClient.parse_common_location_path ) - from_service_account_file = ( - StreamingVideoIntelligenceServiceClient.from_service_account_file - ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + StreamingVideoIntelligenceServiceAsyncClient: The constructed client. + """ + return StreamingVideoIntelligenceServiceClient.from_service_account_info.__func__(StreamingVideoIntelligenceServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + StreamingVideoIntelligenceServiceAsyncClient: The constructed client. + """ + return StreamingVideoIntelligenceServiceClient.from_service_account_file.__func__(StreamingVideoIntelligenceServiceAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property @@ -180,7 +207,7 @@ def streaming_annotate_video( (not REST). Args: - requests (AsyncIterator[`~.video_intelligence.StreamingAnnotateVideoRequest`]): + requests (AsyncIterator[`google.cloud.videointelligence_v1p3beta1.types.StreamingAnnotateVideoRequest`]): The request object AsyncIterator. The top-level message sent by the client for the `StreamingAnnotateVideo` method. Multiple `StreamingAnnotateVideoRequest` messages are sent. The @@ -194,12 +221,11 @@ def streaming_annotate_video( sent along with the request as metadata. Returns: - AsyncIterable[~.video_intelligence.StreamingAnnotateVideoResponse]: - ``StreamingAnnotateVideoResponse`` is the only message - returned to the client by ``StreamingAnnotateVideo``. A - series of zero or more - ``StreamingAnnotateVideoResponse`` messages are streamed - back to the client. + AsyncIterable[google.cloud.videointelligence_v1p3beta1.types.StreamingAnnotateVideoResponse]: + StreamingAnnotateVideoResponse is the only message returned to the client + by StreamingAnnotateVideo. A series of zero or more + StreamingAnnotateVideoResponse messages are streamed + back to the client. """ @@ -214,6 +240,7 @@ def streaming_annotate_video( predicate=retries.if_exception_type( exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), + deadline=10800.0, ), default_timeout=10800.0, client_info=DEFAULT_CLIENT_INFO, diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/client.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/client.py index 48eb476b0e6c..9780eaf95789 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/client.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/client.py @@ -131,6 +131,22 @@ def _get_default_mtls_endpoint(api_endpoint): DEFAULT_ENDPOINT ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + StreamingVideoIntelligenceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -143,7 +159,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): kwargs: Additional arguments to pass to the constructor. Returns: - {@api.name}: The constructed client. + StreamingVideoIntelligenceServiceClient: The constructed client. """ credentials = service_account.Credentials.from_service_account_file(filename) kwargs["credentials"] = credentials @@ -235,10 +251,10 @@ def __init__( credentials identify the application to the service; if none are specified, the client will attempt to ascertain the credentials from the environment. - transport (Union[str, ~.StreamingVideoIntelligenceServiceTransport]): The + transport (Union[str, StreamingVideoIntelligenceServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the + client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT @@ -274,21 +290,17 @@ def __init__( util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) ) - ssl_credentials = None + client_cert_source_func = None is_mtls = False if use_client_cert: if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) is_mtls = True + client_cert_source_func = client_options.client_cert_source else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None + is_mtls = mtls.has_default_client_cert_source() + client_cert_source_func = ( + mtls.default_client_cert_source() if is_mtls else None + ) # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -331,7 +343,7 @@ def __init__( credentials_file=client_options.credentials_file, host=api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, ) @@ -350,7 +362,7 @@ def streaming_annotate_video( (not REST). Args: - requests (Iterator[`~.video_intelligence.StreamingAnnotateVideoRequest`]): + requests (Iterator[google.cloud.videointelligence_v1p3beta1.types.StreamingAnnotateVideoRequest]): The request object iterator. The top-level message sent by the client for the `StreamingAnnotateVideo` method. Multiple `StreamingAnnotateVideoRequest` messages are sent. The @@ -364,12 +376,11 @@ def streaming_annotate_video( sent along with the request as metadata. Returns: - Iterable[~.video_intelligence.StreamingAnnotateVideoResponse]: - ``StreamingAnnotateVideoResponse`` is the only message - returned to the client by ``StreamingAnnotateVideo``. A - series of zero or more - ``StreamingAnnotateVideoResponse`` messages are streamed - back to the client. + Iterable[google.cloud.videointelligence_v1p3beta1.types.StreamingAnnotateVideoResponse]: + StreamingAnnotateVideoResponse is the only message returned to the client + by StreamingAnnotateVideo. A series of zero or more + StreamingAnnotateVideoResponse messages are streamed + back to the client. """ diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/base.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/base.py index 62df02325a9b..c0089a2e64d1 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/base.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/base.py @@ -69,10 +69,10 @@ def __init__( scope (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. """ # Save the hostname. Default to port 443 (HTTPS) if none is specified. @@ -80,6 +80,9 @@ def __init__( host += ":443" self._host = host + # Save the scopes. + self._scopes = scopes or self.AUTH_SCOPES + # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: @@ -89,20 +92,17 @@ def __init__( if credentials_file is not None: credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=scopes, quota_project_id=quota_project_id + credentials_file, scopes=self._scopes, quota_project_id=quota_project_id ) elif credentials is None: credentials, _ = auth.default( - scopes=scopes, quota_project_id=quota_project_id + scopes=self._scopes, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials - # Lifted into its own function so it can be stubbed out during tests. - self._prep_wrapped_messages(client_info) - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -115,6 +115,7 @@ def _prep_wrapped_messages(self, client_info): predicate=retries.if_exception_type( exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), + deadline=10800.0, ), default_timeout=10800.0, client_info=client_info, diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc.py index 5d2fa81e4b20..7ba3e9994de8 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc.py @@ -59,6 +59,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -89,6 +90,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -103,72 +108,60 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -176,17 +169,8 @@ def __init__( ], ) - self._stubs = {} # type: Dict[str, Callable] - - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @classmethod def create_channel( @@ -200,7 +184,7 @@ def create_channel( ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc_asyncio.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc_asyncio.py index 87cafbbdfdea..e7a7cb54d81f 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc_asyncio.py @@ -63,7 +63,7 @@ def create_channel( ) -> aio.Channel: """Create and return a gRPC AsyncIO channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If @@ -103,6 +103,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -134,12 +135,16 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -148,72 +153,60 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials - - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -221,17 +214,8 @@ def __init__( ], ) - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) - - self._stubs = {} + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @property def grpc_channel(self) -> aio.Channel: diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/async_client.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/async_client.py index 43004c36dee1..0c2d80d53456 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/async_client.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/async_client.py @@ -78,7 +78,36 @@ class VideoIntelligenceServiceAsyncClient: VideoIntelligenceServiceClient.parse_common_location_path ) - from_service_account_file = VideoIntelligenceServiceClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceAsyncClient: The constructed client. + """ + return VideoIntelligenceServiceClient.from_service_account_info.__func__(VideoIntelligenceServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceAsyncClient: The constructed client. + """ + return VideoIntelligenceServiceClient.from_service_account_file.__func__(VideoIntelligenceServiceAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property @@ -160,7 +189,7 @@ async def annotate_video( contains ``AnnotateVideoResponse`` (results). Args: - request (:class:`~.video_intelligence.AnnotateVideoRequest`): + request (:class:`google.cloud.videointelligence_v1p3beta1.types.AnnotateVideoRequest`): The request object. Video annotation request. input_uri (:class:`str`): Input video location. Currently, only `Cloud @@ -177,12 +206,14 @@ async def annotate_video( If unset, the input video should be embedded in the request as ``input_content``. If set, ``input_content`` must be unset. + This corresponds to the ``input_uri`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - features (:class:`Sequence[~.video_intelligence.Feature]`): + features (:class:`Sequence[google.cloud.videointelligence_v1p3beta1.types.Feature]`): Required. Requested video annotation features. + This corresponds to the ``features`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -194,15 +225,12 @@ async def annotate_video( sent along with the request as metadata. Returns: - ~.operation_async.AsyncOperation: + google.api_core.operation_async.AsyncOperation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.video_intelligence.AnnotateVideoResponse``: - Video annotation response. Included in the ``response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.videointelligence_v1p3beta1.types.AnnotateVideoResponse` Video annotation response. Included in the response + field of the Operation returned by the GetOperation + call of the google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -237,6 +265,7 @@ async def annotate_video( predicate=retries.if_exception_type( exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), + deadline=600.0, ), default_timeout=600.0, client_info=DEFAULT_CLIENT_INFO, diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/client.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/client.py index 526c99d7b713..80b61de87c49 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/client.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/client.py @@ -113,6 +113,22 @@ def _get_default_mtls_endpoint(api_endpoint): DEFAULT_ENDPOINT ) + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + VideoIntelligenceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info(info) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials @@ -125,7 +141,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): kwargs: Additional arguments to pass to the constructor. Returns: - {@api.name}: The constructed client. + VideoIntelligenceServiceClient: The constructed client. """ credentials = service_account.Credentials.from_service_account_file(filename) kwargs["credentials"] = credentials @@ -217,10 +233,10 @@ def __init__( credentials identify the application to the service; if none are specified, the client will attempt to ascertain the credentials from the environment. - transport (Union[str, ~.VideoIntelligenceServiceTransport]): The + transport (Union[str, VideoIntelligenceServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (client_options_lib.ClientOptions): Custom options for the + client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT @@ -256,21 +272,17 @@ def __init__( util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")) ) - ssl_credentials = None + client_cert_source_func = None is_mtls = False if use_client_cert: if client_options.client_cert_source: - import grpc # type: ignore - - cert, key = client_options.client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) is_mtls = True + client_cert_source_func = client_options.client_cert_source else: - creds = SslCredentials() - is_mtls = creds.is_mtls - ssl_credentials = creds.ssl_credentials if is_mtls else None + is_mtls = mtls.has_default_client_cert_source() + client_cert_source_func = ( + mtls.default_client_cert_source() if is_mtls else None + ) # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -313,7 +325,7 @@ def __init__( credentials_file=client_options.credentials_file, host=api_endpoint, scopes=client_options.scopes, - ssl_channel_credentials=ssl_credentials, + client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, ) @@ -335,9 +347,9 @@ def annotate_video( contains ``AnnotateVideoResponse`` (results). Args: - request (:class:`~.video_intelligence.AnnotateVideoRequest`): + request (google.cloud.videointelligence_v1p3beta1.types.AnnotateVideoRequest): The request object. Video annotation request. - input_uri (:class:`str`): + input_uri (str): Input video location. Currently, only `Cloud Storage `__ URIs are supported. URIs must be specified in the following @@ -352,12 +364,14 @@ def annotate_video( If unset, the input video should be embedded in the request as ``input_content``. If set, ``input_content`` must be unset. + This corresponds to the ``input_uri`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - features (:class:`Sequence[~.video_intelligence.Feature]`): + features (Sequence[google.cloud.videointelligence_v1p3beta1.types.Feature]): Required. Requested video annotation features. + This corresponds to the ``features`` field on the ``request`` instance; if ``request`` is provided, this should not be set. @@ -369,15 +383,12 @@ def annotate_video( sent along with the request as metadata. Returns: - ~.operation.Operation: + google.api_core.operation.Operation: An object representing a long-running operation. - The result type for the operation will be - :class:``~.video_intelligence.AnnotateVideoResponse``: - Video annotation response. Included in the ``response`` - field of the ``Operation`` returned by the - ``GetOperation`` call of the - ``google::longrunning::Operations`` service. + The result type for the operation will be :class:`google.cloud.videointelligence_v1p3beta1.types.AnnotateVideoResponse` Video annotation response. Included in the response + field of the Operation returned by the GetOperation + call of the google::longrunning::Operations service. """ # Create or coerce a protobuf request object. @@ -402,9 +413,8 @@ def annotate_video( if input_uri is not None: request.input_uri = input_uri - - if features: - request.features.extend(features) + if features is not None: + request.features = features # Wrap the RPC method; this adds retry and timeout information, # and friendly error handling. diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/base.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/base.py index d2368ab14f0e..e1f08ea99a32 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/base.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/base.py @@ -71,10 +71,10 @@ def __init__( scope (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. """ # Save the hostname. Default to port 443 (HTTPS) if none is specified. @@ -82,6 +82,9 @@ def __init__( host += ":443" self._host = host + # Save the scopes. + self._scopes = scopes or self.AUTH_SCOPES + # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: @@ -91,20 +94,17 @@ def __init__( if credentials_file is not None: credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=scopes, quota_project_id=quota_project_id + credentials_file, scopes=self._scopes, quota_project_id=quota_project_id ) elif credentials is None: credentials, _ = auth.default( - scopes=scopes, quota_project_id=quota_project_id + scopes=self._scopes, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials - # Lifted into its own function so it can be stubbed out during tests. - self._prep_wrapped_messages(client_info) - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -117,6 +117,7 @@ def _prep_wrapped_messages(self, client_info): predicate=retries.if_exception_type( exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, ), + deadline=600.0, ), default_timeout=600.0, client_info=client_info, diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc.py index d56a623de1b5..af34005dcb9e 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc.py @@ -59,6 +59,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -89,6 +90,10 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -103,72 +108,61 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -176,18 +170,8 @@ def __init__( ], ) - self._stubs = {} # type: Dict[str, Callable] - self._operations_client = None - - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @classmethod def create_channel( @@ -201,7 +185,7 @@ def create_channel( ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc_asyncio.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc_asyncio.py index 57d588c76189..5b84435052a1 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc_asyncio.py @@ -63,7 +63,7 @@ def create_channel( ) -> aio.Channel: """Create and return a gRPC AsyncIO channel object. Args: - address (Optional[str]): The host for the channel to use. + host (Optional[str]): The host for the channel to use. credentials (Optional[~.Credentials]): The authorization credentials to attach to requests. These credentials identify this application to the service. If @@ -103,6 +103,7 @@ def __init__( api_mtls_endpoint: str = None, client_cert_source: Callable[[], Tuple[bytes, bytes]] = None, ssl_channel_credentials: grpc.ChannelCredentials = None, + client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None, quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: @@ -134,12 +135,16 @@ def __init__( ``api_mtls_endpoint`` is None. ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials for grpc channel. It is ignored if ``channel`` is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure mutual TLS channel. It is + ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -148,72 +153,61 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - warnings.warn( - "api_mtls_endpoint and client_cert_source are deprecated", - DeprecationWarning, - ) - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - ssl_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) else: - ssl_credentials = SslCredentials().ssl_credentials + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - # create a new channel. The provided one is ignored. - self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials - else: - host = host if ":" in host else host + ":443" - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, - ssl_credentials=ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -221,18 +215,8 @@ def __init__( ], ) - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) - - self._stubs = {} - self._operations_client = None + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @property def grpc_channel(self) -> aio.Channel: diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/types/__init__.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/types/__init__.py index 539d491a5737..393ab02f26e9 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/types/__init__.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/types/__init__.py @@ -16,125 +16,125 @@ # from .video_intelligence import ( + AnnotateVideoProgress, AnnotateVideoRequest, - VideoContext, - LabelDetectionConfig, - ShotChangeDetectionConfig, - ObjectTrackingConfig, - ExplicitContentDetectionConfig, - FaceDetectionConfig, - PersonDetectionConfig, - TextDetectionConfig, - VideoSegment, - LabelSegment, - LabelFrame, - Entity, - LabelAnnotation, - ExplicitContentFrame, - ExplicitContentAnnotation, - NormalizedBoundingBox, - TimestampedObject, - Track, - DetectedAttribute, + AnnotateVideoResponse, Celebrity, - CelebrityTrack, CelebrityRecognitionAnnotation, + CelebrityTrack, + DetectedAttribute, DetectedLandmark, + Entity, + ExplicitContentAnnotation, + ExplicitContentDetectionConfig, + ExplicitContentFrame, FaceDetectionAnnotation, + FaceDetectionConfig, + LabelAnnotation, + LabelDetectionConfig, + LabelFrame, + LabelSegment, + LogoRecognitionAnnotation, + NormalizedBoundingBox, + NormalizedBoundingPoly, + NormalizedVertex, + ObjectTrackingAnnotation, + ObjectTrackingConfig, + ObjectTrackingFrame, PersonDetectionAnnotation, - VideoAnnotationResults, - AnnotateVideoResponse, - VideoAnnotationProgress, - AnnotateVideoProgress, - SpeechTranscriptionConfig, + PersonDetectionConfig, + ShotChangeDetectionConfig, SpeechContext, - SpeechTranscription, SpeechRecognitionAlternative, - WordInfo, - NormalizedVertex, - NormalizedBoundingPoly, - TextSegment, - TextFrame, - TextAnnotation, - ObjectTrackingFrame, - ObjectTrackingAnnotation, - LogoRecognitionAnnotation, + SpeechTranscription, + SpeechTranscriptionConfig, StreamingAnnotateVideoRequest, - StreamingVideoConfig, StreamingAnnotateVideoResponse, - StreamingVideoAnnotationResults, - StreamingShotChangeDetectionConfig, - StreamingLabelDetectionConfig, - StreamingExplicitContentDetectionConfig, - StreamingObjectTrackingConfig, StreamingAutomlActionRecognitionConfig, StreamingAutomlClassificationConfig, StreamingAutomlObjectTrackingConfig, + StreamingExplicitContentDetectionConfig, + StreamingLabelDetectionConfig, + StreamingObjectTrackingConfig, + StreamingShotChangeDetectionConfig, StreamingStorageConfig, + StreamingVideoAnnotationResults, + StreamingVideoConfig, + TextAnnotation, + TextDetectionConfig, + TextFrame, + TextSegment, + TimestampedObject, + Track, + VideoAnnotationProgress, + VideoAnnotationResults, + VideoContext, + VideoSegment, + WordInfo, + Feature, LabelDetectionMode, Likelihood, StreamingFeature, - Feature, ) __all__ = ( + "AnnotateVideoProgress", "AnnotateVideoRequest", - "VideoContext", - "LabelDetectionConfig", - "ShotChangeDetectionConfig", - "ObjectTrackingConfig", - "ExplicitContentDetectionConfig", - "FaceDetectionConfig", - "PersonDetectionConfig", - "TextDetectionConfig", - "VideoSegment", - "LabelSegment", - "LabelFrame", - "Entity", - "LabelAnnotation", - "ExplicitContentFrame", - "ExplicitContentAnnotation", - "NormalizedBoundingBox", - "TimestampedObject", - "Track", - "DetectedAttribute", + "AnnotateVideoResponse", "Celebrity", - "CelebrityTrack", "CelebrityRecognitionAnnotation", + "CelebrityTrack", + "DetectedAttribute", "DetectedLandmark", + "Entity", + "ExplicitContentAnnotation", + "ExplicitContentDetectionConfig", + "ExplicitContentFrame", "FaceDetectionAnnotation", + "FaceDetectionConfig", + "LabelAnnotation", + "LabelDetectionConfig", + "LabelFrame", + "LabelSegment", + "LogoRecognitionAnnotation", + "NormalizedBoundingBox", + "NormalizedBoundingPoly", + "NormalizedVertex", + "ObjectTrackingAnnotation", + "ObjectTrackingConfig", + "ObjectTrackingFrame", "PersonDetectionAnnotation", - "VideoAnnotationResults", - "AnnotateVideoResponse", - "VideoAnnotationProgress", - "AnnotateVideoProgress", - "SpeechTranscriptionConfig", + "PersonDetectionConfig", + "ShotChangeDetectionConfig", "SpeechContext", - "SpeechTranscription", "SpeechRecognitionAlternative", - "WordInfo", - "NormalizedVertex", - "NormalizedBoundingPoly", - "TextSegment", - "TextFrame", - "TextAnnotation", - "ObjectTrackingFrame", - "ObjectTrackingAnnotation", - "LogoRecognitionAnnotation", + "SpeechTranscription", + "SpeechTranscriptionConfig", "StreamingAnnotateVideoRequest", - "StreamingVideoConfig", "StreamingAnnotateVideoResponse", - "StreamingVideoAnnotationResults", - "StreamingShotChangeDetectionConfig", - "StreamingLabelDetectionConfig", - "StreamingExplicitContentDetectionConfig", - "StreamingObjectTrackingConfig", "StreamingAutomlActionRecognitionConfig", "StreamingAutomlClassificationConfig", "StreamingAutomlObjectTrackingConfig", + "StreamingExplicitContentDetectionConfig", + "StreamingLabelDetectionConfig", + "StreamingObjectTrackingConfig", + "StreamingShotChangeDetectionConfig", "StreamingStorageConfig", + "StreamingVideoAnnotationResults", + "StreamingVideoConfig", + "TextAnnotation", + "TextDetectionConfig", + "TextFrame", + "TextSegment", + "TimestampedObject", + "Track", + "VideoAnnotationProgress", + "VideoAnnotationResults", + "VideoContext", + "VideoSegment", + "WordInfo", + "Feature", "LabelDetectionMode", "Likelihood", "StreamingFeature", - "Feature", ) diff --git a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/types/video_intelligence.py b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/types/video_intelligence.py index 31bfa49d7c51..4cce08e7caed 100644 --- a/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/types/video_intelligence.py +++ b/packages/google-cloud-videointelligence/google/cloud/videointelligence_v1p3beta1/types/video_intelligence.py @@ -155,10 +155,10 @@ class AnnotateVideoRequest(proto.Message): The video data bytes. If unset, the input video(s) should be specified via the ``input_uri``. If set, ``input_uri`` must be unset. - features (Sequence[~.video_intelligence.Feature]): + features (Sequence[google.cloud.videointelligence_v1p3beta1.types.Feature]): Required. Requested video annotation features. - video_context (~.video_intelligence.VideoContext): + video_context (google.cloud.videointelligence_v1p3beta1.types.VideoContext): Additional video context and/or feature- pecific parameters. output_uri (str): @@ -194,26 +194,26 @@ class VideoContext(proto.Message): r"""Video context and/or feature-specific parameters. Attributes: - segments (Sequence[~.video_intelligence.VideoSegment]): + segments (Sequence[google.cloud.videointelligence_v1p3beta1.types.VideoSegment]): Video segments to annotate. The segments may overlap and are not required to be contiguous or span the whole video. If unspecified, each video is treated as a single segment. - label_detection_config (~.video_intelligence.LabelDetectionConfig): + label_detection_config (google.cloud.videointelligence_v1p3beta1.types.LabelDetectionConfig): Config for LABEL_DETECTION. - shot_change_detection_config (~.video_intelligence.ShotChangeDetectionConfig): + shot_change_detection_config (google.cloud.videointelligence_v1p3beta1.types.ShotChangeDetectionConfig): Config for SHOT_CHANGE_DETECTION. - explicit_content_detection_config (~.video_intelligence.ExplicitContentDetectionConfig): + explicit_content_detection_config (google.cloud.videointelligence_v1p3beta1.types.ExplicitContentDetectionConfig): Config for EXPLICIT_CONTENT_DETECTION. - face_detection_config (~.video_intelligence.FaceDetectionConfig): + face_detection_config (google.cloud.videointelligence_v1p3beta1.types.FaceDetectionConfig): Config for FACE_DETECTION. - speech_transcription_config (~.video_intelligence.SpeechTranscriptionConfig): + speech_transcription_config (google.cloud.videointelligence_v1p3beta1.types.SpeechTranscriptionConfig): Config for SPEECH_TRANSCRIPTION. - text_detection_config (~.video_intelligence.TextDetectionConfig): + text_detection_config (google.cloud.videointelligence_v1p3beta1.types.TextDetectionConfig): Config for TEXT_DETECTION. - person_detection_config (~.video_intelligence.PersonDetectionConfig): + person_detection_config (google.cloud.videointelligence_v1p3beta1.types.PersonDetectionConfig): Config for PERSON_DETECTION. - object_tracking_config (~.video_intelligence.ObjectTrackingConfig): + object_tracking_config (google.cloud.videointelligence_v1p3beta1.types.ObjectTrackingConfig): Config for OBJECT_TRACKING. """ @@ -256,7 +256,7 @@ class LabelDetectionConfig(proto.Message): r"""Config for LABEL_DETECTION. Attributes: - label_detection_mode (~.video_intelligence.LabelDetectionMode): + label_detection_mode (google.cloud.videointelligence_v1p3beta1.types.LabelDetectionMode): What labels should be detected with LABEL_DETECTION, in addition to video-level labels or segment-level labels. If unspecified, defaults to ``SHOT_MODE``. @@ -413,11 +413,11 @@ class VideoSegment(proto.Message): r"""Video segment. Attributes: - start_time_offset (~.duration.Duration): + start_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the start of the segment (inclusive). - end_time_offset (~.duration.Duration): + end_time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the end of the segment (inclusive). @@ -432,7 +432,7 @@ class LabelSegment(proto.Message): r"""Video segment level annotation results for label detection. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1p3beta1.types.VideoSegment): Video segment where a label was detected. confidence (float): Confidence that the label is accurate. Range: [0, 1]. @@ -447,7 +447,7 @@ class LabelFrame(proto.Message): r"""Video frame level annotation results for label detection. Attributes: - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this location. @@ -485,17 +485,17 @@ class LabelAnnotation(proto.Message): r"""Label annotation. Attributes: - entity (~.video_intelligence.Entity): + entity (google.cloud.videointelligence_v1p3beta1.types.Entity): Detected entity. - category_entities (Sequence[~.video_intelligence.Entity]): + category_entities (Sequence[google.cloud.videointelligence_v1p3beta1.types.Entity]): Common categories for the detected entity. For example, when the label is ``Terrier``, the category is likely ``dog``. And in some cases there might be more than one categories e.g., ``Terrier`` could also be a ``pet``. - segments (Sequence[~.video_intelligence.LabelSegment]): + segments (Sequence[google.cloud.videointelligence_v1p3beta1.types.LabelSegment]): All video segments where a label was detected. - frames (Sequence[~.video_intelligence.LabelFrame]): + frames (Sequence[google.cloud.videointelligence_v1p3beta1.types.LabelFrame]): All video frames where a label was detected. """ @@ -512,11 +512,11 @@ class ExplicitContentFrame(proto.Message): r"""Video frame level annotation results for explicit content. Attributes: - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this location. - pornography_likelihood (~.video_intelligence.Likelihood): + pornography_likelihood (google.cloud.videointelligence_v1p3beta1.types.Likelihood): Likelihood of the pornography content.. """ @@ -531,7 +531,7 @@ class ExplicitContentAnnotation(proto.Message): frame, no annotations are present for that frame. Attributes: - frames (Sequence[~.video_intelligence.ExplicitContentFrame]): + frames (Sequence[google.cloud.videointelligence_v1p3beta1.types.ExplicitContentFrame]): All video frames where explicit content was detected. """ @@ -570,17 +570,17 @@ class TimestampedObject(proto.Message): attributes, and located with normalized_bounding_box. Attributes: - normalized_bounding_box (~.video_intelligence.NormalizedBoundingBox): + normalized_bounding_box (google.cloud.videointelligence_v1p3beta1.types.NormalizedBoundingBox): Normalized Bounding box in a frame, where the object is located. - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Time-offset, relative to the beginning of the video, corresponding to the video frame for this object. - attributes (Sequence[~.video_intelligence.DetectedAttribute]): + attributes (Sequence[google.cloud.videointelligence_v1p3beta1.types.DetectedAttribute]): Optional. The attributes of the object in the bounding box. - landmarks (Sequence[~.video_intelligence.DetectedLandmark]): + landmarks (Sequence[google.cloud.videointelligence_v1p3beta1.types.DetectedLandmark]): Optional. The detected landmarks. """ @@ -603,12 +603,12 @@ class Track(proto.Message): r"""A track of an object instance. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1p3beta1.types.VideoSegment): Video segment of a track. - timestamped_objects (Sequence[~.video_intelligence.TimestampedObject]): + timestamped_objects (Sequence[google.cloud.videointelligence_v1p3beta1.types.TimestampedObject]): The object with timestamp and attributes per frame in the track. - attributes (Sequence[~.video_intelligence.DetectedAttribute]): + attributes (Sequence[google.cloud.videointelligence_v1p3beta1.types.DetectedAttribute]): Optional. Attributes in the track level. confidence (float): Optional. The confidence score of the tracked @@ -681,10 +681,10 @@ class CelebrityTrack(proto.Message): not have any matched celebrities. Attributes: - celebrities (Sequence[~.video_intelligence.CelebrityTrack.RecognizedCelebrity]): + celebrities (Sequence[google.cloud.videointelligence_v1p3beta1.types.CelebrityTrack.RecognizedCelebrity]): Top N match of the celebrities for the face in this track. - face_track (~.video_intelligence.Track): + face_track (google.cloud.videointelligence_v1p3beta1.types.Track): A track of a person's face. """ @@ -692,7 +692,7 @@ class RecognizedCelebrity(proto.Message): r"""The recognized celebrity with confidence score. Attributes: - celebrity (~.video_intelligence.Celebrity): + celebrity (google.cloud.videointelligence_v1p3beta1.types.Celebrity): The recognized celebrity. confidence (float): Recognition confidence. Range [0, 1]. @@ -713,7 +713,7 @@ class CelebrityRecognitionAnnotation(proto.Message): r"""Celebrity recognition annotation per video. Attributes: - celebrity_tracks (Sequence[~.video_intelligence.CelebrityTrack]): + celebrity_tracks (Sequence[google.cloud.videointelligence_v1p3beta1.types.CelebrityTrack]): The tracks detected from the input video, including recognized celebrities and other detected faces in the video. @@ -732,7 +732,7 @@ class DetectedLandmark(proto.Message): name (str): The name of this landmark, for example, left_hand, right_shoulder. - point (~.video_intelligence.NormalizedVertex): + point (google.cloud.videointelligence_v1p3beta1.types.NormalizedVertex): The 2D point of the detected landmark using the normalized image coordindate system. The normalized coordinates have the range from 0 to @@ -752,7 +752,7 @@ class FaceDetectionAnnotation(proto.Message): r"""Face detection annotation. Attributes: - tracks (Sequence[~.video_intelligence.Track]): + tracks (Sequence[google.cloud.videointelligence_v1p3beta1.types.Track]): The face tracks with attributes. thumbnail (bytes): The thumbnail of a person's face. @@ -767,7 +767,7 @@ class PersonDetectionAnnotation(proto.Message): r"""Person detection annotation per video. Attributes: - tracks (Sequence[~.video_intelligence.Track]): + tracks (Sequence[google.cloud.videointelligence_v1p3beta1.types.Track]): The detected tracks of a person. """ @@ -781,13 +781,13 @@ class VideoAnnotationResults(proto.Message): input_uri (str): Video file location in `Cloud Storage `__. - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1p3beta1.types.VideoSegment): Video segment on which the annotation is run. - segment_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + segment_label_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.LabelAnnotation]): Topical label annotations on video level or user-specified segment level. There is exactly one element for each unique label. - segment_presence_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + segment_presence_label_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.LabelAnnotation]): Presence label annotations on video level or user-specified segment level. There is exactly one element for each unique label. Compared to the existing topical @@ -796,11 +796,11 @@ class VideoAnnotationResults(proto.Message): and is made available only when the client sets ``LabelDetectionConfig.model`` to "builtin/latest" in the request. - shot_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + shot_label_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.LabelAnnotation]): Topical label annotations on shot level. There is exactly one element for each unique label. - shot_presence_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + shot_presence_label_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.LabelAnnotation]): Presence label annotations on shot level. There is exactly one element for each unique label. Compared to the existing topical ``shot_label_annotations``, this field presents more @@ -808,35 +808,35 @@ class VideoAnnotationResults(proto.Message): and is made available only when the client sets ``LabelDetectionConfig.model`` to "builtin/latest" in the request. - frame_label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + frame_label_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.LabelAnnotation]): Label annotations on frame level. There is exactly one element for each unique label. - face_detection_annotations (Sequence[~.video_intelligence.FaceDetectionAnnotation]): + face_detection_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.FaceDetectionAnnotation]): Face detection annotations. - shot_annotations (Sequence[~.video_intelligence.VideoSegment]): + shot_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.VideoSegment]): Shot annotations. Each shot is represented as a video segment. - explicit_annotation (~.video_intelligence.ExplicitContentAnnotation): + explicit_annotation (google.cloud.videointelligence_v1p3beta1.types.ExplicitContentAnnotation): Explicit content annotation. - speech_transcriptions (Sequence[~.video_intelligence.SpeechTranscription]): + speech_transcriptions (Sequence[google.cloud.videointelligence_v1p3beta1.types.SpeechTranscription]): Speech transcription. - text_annotations (Sequence[~.video_intelligence.TextAnnotation]): + text_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.TextAnnotation]): OCR text detection and tracking. Annotations for list of detected text snippets. Each will have list of frame information associated with it. - object_annotations (Sequence[~.video_intelligence.ObjectTrackingAnnotation]): + object_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.ObjectTrackingAnnotation]): Annotations for list of objects detected and tracked in video. - logo_recognition_annotations (Sequence[~.video_intelligence.LogoRecognitionAnnotation]): + logo_recognition_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.LogoRecognitionAnnotation]): Annotations for list of logos detected, tracked and recognized in video. - person_detection_annotations (Sequence[~.video_intelligence.PersonDetectionAnnotation]): + person_detection_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.PersonDetectionAnnotation]): Person detection annotations. - celebrity_recognition_annotations (~.video_intelligence.CelebrityRecognitionAnnotation): + celebrity_recognition_annotations (google.cloud.videointelligence_v1p3beta1.types.CelebrityRecognitionAnnotation): Celebrity recognition annotations. - error (~.status.Status): + error (google.rpc.status_pb2.Status): If set, indicates an error. Note that for a single ``AnnotateVideoRequest`` some videos may succeed and some may fail. @@ -911,7 +911,7 @@ class AnnotateVideoResponse(proto.Message): ``google::longrunning::Operations`` service. Attributes: - annotation_results (Sequence[~.video_intelligence.VideoAnnotationResults]): + annotation_results (Sequence[google.cloud.videointelligence_v1p3beta1.types.VideoAnnotationResults]): Annotation results for all videos specified in ``AnnotateVideoRequest``. """ @@ -931,14 +931,14 @@ class VideoAnnotationProgress(proto.Message): progress_percent (int): Approximate percentage processed thus far. Guaranteed to be 100 when fully processed. - start_time (~.timestamp.Timestamp): + start_time (google.protobuf.timestamp_pb2.Timestamp): Time when the request was received. - update_time (~.timestamp.Timestamp): + update_time (google.protobuf.timestamp_pb2.Timestamp): Time of the most recent update. - feature (~.video_intelligence.Feature): + feature (google.cloud.videointelligence_v1p3beta1.types.Feature): Specifies which feature is being tracked if the request contains more than one feature. - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1p3beta1.types.VideoSegment): Specifies which segment is being tracked if the request contains more than one segment. """ @@ -962,7 +962,7 @@ class AnnotateVideoProgress(proto.Message): ``google::longrunning::Operations`` service. Attributes: - annotation_progress (Sequence[~.video_intelligence.VideoAnnotationProgress]): + annotation_progress (Sequence[google.cloud.videointelligence_v1p3beta1.types.VideoAnnotationProgress]): Progress metadata for all videos specified in ``AnnotateVideoRequest``. """ @@ -996,7 +996,7 @@ class SpeechTranscriptionConfig(proto.Message): character in each filtered word with asterisks, e.g. "f***". If set to ``false`` or omitted, profanities won't be filtered out. - speech_contexts (Sequence[~.video_intelligence.SpeechContext]): + speech_contexts (Sequence[google.cloud.videointelligence_v1p3beta1.types.SpeechContext]): Optional. A means to provide context to assist the speech recognition. enable_automatic_punctuation (bool): @@ -1079,7 +1079,7 @@ class SpeechTranscription(proto.Message): audio. Attributes: - alternatives (Sequence[~.video_intelligence.SpeechRecognitionAlternative]): + alternatives (Sequence[google.cloud.videointelligence_v1p3beta1.types.SpeechRecognitionAlternative]): May contain one or more recognition hypotheses (up to the maximum specified in ``max_alternatives``). These alternatives are ordered in terms of accuracy, with the top @@ -1115,7 +1115,7 @@ class SpeechRecognitionAlternative(proto.Message): accurate and users should not rely on it to be always provided. The default of 0.0 is a sentinel value indicating ``confidence`` was not set. - words (Sequence[~.video_intelligence.WordInfo]): + words (Sequence[google.cloud.videointelligence_v1p3beta1.types.WordInfo]): Output only. A list of word-specific information for each recognized word. Note: When ``enable_speaker_diarization`` is set to true, you will see all the words from the @@ -1135,13 +1135,13 @@ class WordInfo(proto.Message): set, such as ``enable_word_time_offsets``. Attributes: - start_time (~.duration.Duration): + start_time (google.protobuf.duration_pb2.Duration): Time offset relative to the beginning of the audio, and corresponding to the start of the spoken word. This field is only set if ``enable_word_time_offsets=true`` and only in the top hypothesis. This is an experimental feature and the accuracy of the time offset can vary. - end_time (~.duration.Duration): + end_time (google.protobuf.duration_pb2.Duration): Time offset relative to the beginning of the audio, and corresponding to the end of the spoken word. This field is only set if ``enable_word_time_offsets=true`` and only in @@ -1209,7 +1209,7 @@ class NormalizedBoundingPoly(proto.Message): calculations for location of the box. Attributes: - vertices (Sequence[~.video_intelligence.NormalizedVertex]): + vertices (Sequence[google.cloud.videointelligence_v1p3beta1.types.NormalizedVertex]): Normalized vertices of the bounding polygon. """ @@ -1220,14 +1220,14 @@ class TextSegment(proto.Message): r"""Video segment level annotation results for text detection. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1p3beta1.types.VideoSegment): Video segment where a text snippet was detected. confidence (float): Confidence for the track of detected text. It is calculated as the highest over all frames where OCR detected text appears. - frames (Sequence[~.video_intelligence.TextFrame]): + frames (Sequence[google.cloud.videointelligence_v1p3beta1.types.TextFrame]): Information related to the frames where OCR detected text appears. """ @@ -1245,10 +1245,10 @@ class TextFrame(proto.Message): locations for the frames containing detected OCR text snippets. Attributes: - rotated_bounding_box (~.video_intelligence.NormalizedBoundingPoly): + rotated_bounding_box (google.cloud.videointelligence_v1p3beta1.types.NormalizedBoundingPoly): Bounding polygon of the detected text for this frame. - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): Timestamp of this frame. """ @@ -1267,7 +1267,7 @@ class TextAnnotation(proto.Message): Attributes: text (str): The detected text. - segments (Sequence[~.video_intelligence.TextSegment]): + segments (Sequence[google.cloud.videointelligence_v1p3beta1.types.TextSegment]): All video segments where OCR detected text appears. """ @@ -1283,10 +1283,10 @@ class ObjectTrackingFrame(proto.Message): confidence. Attributes: - normalized_bounding_box (~.video_intelligence.NormalizedBoundingBox): + normalized_bounding_box (google.cloud.videointelligence_v1p3beta1.types.NormalizedBoundingBox): The normalized bounding box location of this object track for the frame. - time_offset (~.duration.Duration): + time_offset (google.protobuf.duration_pb2.Duration): The timestamp of the frame in microseconds. """ @@ -1301,7 +1301,7 @@ class ObjectTrackingAnnotation(proto.Message): r"""Annotations corresponding to one tracked object. Attributes: - segment (~.video_intelligence.VideoSegment): + segment (google.cloud.videointelligence_v1p3beta1.types.VideoSegment): Non-streaming batch mode ONLY. Each object track corresponds to one video segment where it appears. @@ -1312,13 +1312,13 @@ class ObjectTrackingAnnotation(proto.Message): a unique identifiable integer track_id so that the customers can correlate the results of the ongoing ObjectTrackAnnotation of the same track_id over time. - entity (~.video_intelligence.Entity): + entity (google.cloud.videointelligence_v1p3beta1.types.Entity): Entity to specify the object category that this track is labeled as. confidence (float): Object category's labeling confidence of this track. - frames (Sequence[~.video_intelligence.ObjectTrackingFrame]): + frames (Sequence[google.cloud.videointelligence_v1p3beta1.types.ObjectTrackingFrame]): Information corresponding to all frames where this object track appears. Non-streaming batch mode: it may be one or multiple @@ -1347,15 +1347,15 @@ class LogoRecognitionAnnotation(proto.Message): recognized logo class. Attributes: - entity (~.video_intelligence.Entity): + entity (google.cloud.videointelligence_v1p3beta1.types.Entity): Entity category information to specify the logo class that all the logo tracks within this LogoRecognitionAnnotation are recognized as. - tracks (Sequence[~.video_intelligence.Track]): + tracks (Sequence[google.cloud.videointelligence_v1p3beta1.types.Track]): All logo tracks where the recognized logo appears. Each track corresponds to one logo instance appearing in consecutive frames. - segments (Sequence[~.video_intelligence.VideoSegment]): + segments (Sequence[google.cloud.videointelligence_v1p3beta1.types.VideoSegment]): All video segments where the recognized logo appears. There might be multiple instances of the same logo class appearing in one @@ -1377,7 +1377,7 @@ class StreamingAnnotateVideoRequest(proto.Message): subsequent messages must only contain ``input_content`` data. Attributes: - video_config (~.video_intelligence.StreamingVideoConfig): + video_config (google.cloud.videointelligence_v1p3beta1.types.StreamingVideoConfig): Provides information to the annotator, specifing how to process the request. The first ``AnnotateStreamingVideoRequest`` message must only contain @@ -1408,23 +1408,23 @@ class StreamingVideoConfig(proto.Message): process the request. Attributes: - shot_change_detection_config (~.video_intelligence.StreamingShotChangeDetectionConfig): + shot_change_detection_config (google.cloud.videointelligence_v1p3beta1.types.StreamingShotChangeDetectionConfig): Config for STREAMING_SHOT_CHANGE_DETECTION. - label_detection_config (~.video_intelligence.StreamingLabelDetectionConfig): + label_detection_config (google.cloud.videointelligence_v1p3beta1.types.StreamingLabelDetectionConfig): Config for STREAMING_LABEL_DETECTION. - explicit_content_detection_config (~.video_intelligence.StreamingExplicitContentDetectionConfig): + explicit_content_detection_config (google.cloud.videointelligence_v1p3beta1.types.StreamingExplicitContentDetectionConfig): Config for STREAMING_EXPLICIT_CONTENT_DETECTION. - object_tracking_config (~.video_intelligence.StreamingObjectTrackingConfig): + object_tracking_config (google.cloud.videointelligence_v1p3beta1.types.StreamingObjectTrackingConfig): Config for STREAMING_OBJECT_TRACKING. - automl_action_recognition_config (~.video_intelligence.StreamingAutomlActionRecognitionConfig): + automl_action_recognition_config (google.cloud.videointelligence_v1p3beta1.types.StreamingAutomlActionRecognitionConfig): Config for STREAMING_AUTOML_ACTION_RECOGNITION. - automl_classification_config (~.video_intelligence.StreamingAutomlClassificationConfig): + automl_classification_config (google.cloud.videointelligence_v1p3beta1.types.StreamingAutomlClassificationConfig): Config for STREAMING_AUTOML_CLASSIFICATION. - automl_object_tracking_config (~.video_intelligence.StreamingAutomlObjectTrackingConfig): + automl_object_tracking_config (google.cloud.videointelligence_v1p3beta1.types.StreamingAutomlObjectTrackingConfig): Config for STREAMING_AUTOML_OBJECT_TRACKING. - feature (~.video_intelligence.StreamingFeature): + feature (google.cloud.videointelligence_v1p3beta1.types.StreamingFeature): Requested annotation feature. - storage_config (~.video_intelligence.StreamingStorageConfig): + storage_config (google.cloud.videointelligence_v1p3beta1.types.StreamingStorageConfig): Streaming storage option. By default: storage is disabled. """ @@ -1492,10 +1492,10 @@ class StreamingAnnotateVideoResponse(proto.Message): client. Attributes: - error (~.status.Status): + error (google.rpc.status_pb2.Status): If set, returns a [google.rpc.Status][google.rpc.Status] message that specifies the error for the operation. - annotation_results (~.video_intelligence.StreamingVideoAnnotationResults): + annotation_results (google.cloud.videointelligence_v1p3beta1.types.StreamingVideoAnnotationResults): Streaming annotation results. annotation_results_uri (str): Google Cloud Storage(GCS) URI that stores annotation results @@ -1518,14 +1518,14 @@ class StreamingVideoAnnotationResults(proto.Message): the video that is currently being processed. Attributes: - shot_annotations (Sequence[~.video_intelligence.VideoSegment]): + shot_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.VideoSegment]): Shot annotation results. Each shot is represented as a video segment. - label_annotations (Sequence[~.video_intelligence.LabelAnnotation]): + label_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.LabelAnnotation]): Label annotation results. - explicit_annotation (~.video_intelligence.ExplicitContentAnnotation): + explicit_annotation (google.cloud.videointelligence_v1p3beta1.types.ExplicitContentAnnotation): Explicit content annotation results. - object_annotations (Sequence[~.video_intelligence.ObjectTrackingAnnotation]): + object_annotations (Sequence[google.cloud.videointelligence_v1p3beta1.types.ObjectTrackingAnnotation]): Object tracking results. """ diff --git a/packages/google-cloud-videointelligence/noxfile.py b/packages/google-cloud-videointelligence/noxfile.py index 7b862dfb6f40..a1a80866a51b 100644 --- a/packages/google-cloud-videointelligence/noxfile.py +++ b/packages/google-cloud-videointelligence/noxfile.py @@ -18,6 +18,7 @@ from __future__ import absolute_import import os +import pathlib import shutil import nox @@ -30,6 +31,22 @@ SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"] UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +# 'docfx' is excluded since it only needs to run in 'docs-presubmit' +nox.options.sessions = [ + "unit", + "system", + "cover", + "lint", + "lint_setup_py", + "blacken", + "docs", +] + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + @nox.session(python=DEFAULT_PYTHON_VERSION) def lint(session): @@ -70,17 +87,21 @@ def lint_setup_py(session): def default(session): # Install all test dependencies, then install this package in-place. - session.install("asyncmock", "pytest-asyncio") - session.install( - "mock", "pytest", "pytest-cov", + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" ) - session.install("-e", ".") + session.install("asyncmock", "pytest-asyncio", "-c", constraints_path) + + session.install("mock", "pytest", "pytest-cov", "-c", constraints_path) + + session.install("-e", ".", "-c", constraints_path) # Run py.test against the unit tests. session.run( "py.test", "--quiet", + f"--junitxml=unit_{session.python}_sponge_log.xml", "--cov=google/cloud", "--cov=tests/unit", "--cov-append", @@ -101,6 +122,9 @@ def unit(session): @nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) def system(session): """Run the system test suite.""" + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) system_test_path = os.path.join("tests", "system.py") system_test_folder_path = os.path.join("tests", "system") @@ -110,6 +134,9 @@ def system(session): # Sanity check: Only run tests if the environment variable is set. if not os.environ.get("GOOGLE_APPLICATION_CREDENTIALS", ""): session.skip("Credentials must be set via environment variable") + # Install pyopenssl for mTLS testing. + if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": + session.install("pyopenssl") system_test_exists = os.path.exists(system_test_path) system_test_folder_exists = os.path.exists(system_test_folder_path) @@ -122,16 +149,26 @@ def system(session): # Install all test dependencies, then install this package into the # virtualenv's dist-packages. - session.install( - "mock", "pytest", "google-cloud-testutils", - ) - session.install("-e", ".") + session.install("mock", "pytest", "google-cloud-testutils", "-c", constraints_path) + session.install("-e", ".", "-c", constraints_path) # Run py.test against the system tests. if system_test_exists: - session.run("py.test", "--quiet", system_test_path, *session.posargs) + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_path, + *session.posargs, + ) if system_test_folder_exists: - session.run("py.test", "--quiet", system_test_folder_path, *session.posargs) + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + ) @nox.session(python=DEFAULT_PYTHON_VERSION) diff --git a/packages/google-cloud-videointelligence/renovate.json b/packages/google-cloud-videointelligence/renovate.json index 4fa949311b20..f08bc22c9a55 100644 --- a/packages/google-cloud-videointelligence/renovate.json +++ b/packages/google-cloud-videointelligence/renovate.json @@ -1,5 +1,6 @@ { "extends": [ "config:base", ":preserveSemverRanges" - ] + ], + "ignorePaths": [".pre-commit-config.yaml"] } diff --git a/packages/google-cloud-videointelligence/samples/analyze/noxfile.py b/packages/google-cloud-videointelligence/samples/analyze/noxfile.py index bca0522ec4d9..97bf7da80e39 100644 --- a/packages/google-cloud-videointelligence/samples/analyze/noxfile.py +++ b/packages/google-cloud-videointelligence/samples/analyze/noxfile.py @@ -85,7 +85,7 @@ def get_pytest_env_vars() -> Dict[str, str]: # DO NOT EDIT - automatically generated. # All versions used to tested samples. -ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"] # Any default versions that should be ignored. IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] diff --git a/packages/google-cloud-videointelligence/samples/labels/noxfile.py b/packages/google-cloud-videointelligence/samples/labels/noxfile.py index bca0522ec4d9..97bf7da80e39 100644 --- a/packages/google-cloud-videointelligence/samples/labels/noxfile.py +++ b/packages/google-cloud-videointelligence/samples/labels/noxfile.py @@ -85,7 +85,7 @@ def get_pytest_env_vars() -> Dict[str, str]: # DO NOT EDIT - automatically generated. # All versions used to tested samples. -ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"] # Any default versions that should be ignored. IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] diff --git a/packages/google-cloud-videointelligence/samples/quickstart/noxfile.py b/packages/google-cloud-videointelligence/samples/quickstart/noxfile.py index bca0522ec4d9..97bf7da80e39 100644 --- a/packages/google-cloud-videointelligence/samples/quickstart/noxfile.py +++ b/packages/google-cloud-videointelligence/samples/quickstart/noxfile.py @@ -85,7 +85,7 @@ def get_pytest_env_vars() -> Dict[str, str]: # DO NOT EDIT - automatically generated. # All versions used to tested samples. -ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"] # Any default versions that should be ignored. IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] diff --git a/packages/google-cloud-videointelligence/samples/shotchange/noxfile.py b/packages/google-cloud-videointelligence/samples/shotchange/noxfile.py index bca0522ec4d9..97bf7da80e39 100644 --- a/packages/google-cloud-videointelligence/samples/shotchange/noxfile.py +++ b/packages/google-cloud-videointelligence/samples/shotchange/noxfile.py @@ -85,7 +85,7 @@ def get_pytest_env_vars() -> Dict[str, str]: # DO NOT EDIT - automatically generated. # All versions used to tested samples. -ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"] # Any default versions that should be ignored. IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] diff --git a/packages/google-cloud-videointelligence/setup.py b/packages/google-cloud-videointelligence/setup.py index e4a3d721edb0..b46a5eaff6ee 100644 --- a/packages/google-cloud-videointelligence/setup.py +++ b/packages/google-cloud-videointelligence/setup.py @@ -28,7 +28,7 @@ # 'Development Status :: 4 - Beta' # 'Development Status :: 5 - Production/Stable' release_status = "Development Status :: 5 - Production/Stable" -dependencies = ["google-api-core[grpc] >= 1.22.0, < 2.0.0dev", "proto-plus >= 1.10.0"] +dependencies = ["google-api-core[grpc] >= 1.22.2, < 2.0.0dev", "proto-plus >= 1.10.0"] extras = {"libcst": "libcst >= 0.2.5"} scripts = ["scripts/fixup_keywords.py"] diff --git a/packages/google-cloud-videointelligence/synth.metadata b/packages/google-cloud-videointelligence/synth.metadata index 0762af4fb771..f61d11f6bd55 100644 --- a/packages/google-cloud-videointelligence/synth.metadata +++ b/packages/google-cloud-videointelligence/synth.metadata @@ -3,30 +3,30 @@ { "git": { "name": ".", - "remote": "https://github.com/googleapis/python-videointelligence.git", - "sha": "a1c8715b9167e683bfa42c372904f70e4e1e5124" + "remote": "git@github.com:googleapis/python-videointelligence.git", + "sha": "580512718a893dfa789f071cd58b325057b973fb" } }, { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "dd372aa22ded7a8ba6f0e03a80e06358a3fa0907", - "internalRef": "347055288" + "sha": "336d6f419fe9466e4540083bbfa46a57f67dc92e", + "internalRef": "364666178" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "373861061648b5fe5e0ac4f8a38b32d639ee93e4" + "sha": "86ed43d4f56e6404d068e62e497029018879c771" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "373861061648b5fe5e0ac4f8a38b32d639ee93e4" + "sha": "86ed43d4f56e6404d068e62e497029018879c771" } } ], @@ -76,178 +76,5 @@ "generator": "bazel" } } - ], - "generatedFiles": [ - ".flake8", - ".github/CONTRIBUTING.md", - ".github/ISSUE_TEMPLATE/bug_report.md", - ".github/ISSUE_TEMPLATE/feature_request.md", - ".github/ISSUE_TEMPLATE/support_request.md", - ".github/PULL_REQUEST_TEMPLATE.md", - ".github/release-please.yml", - ".github/snippet-bot.yml", - ".gitignore", - ".kokoro/build.sh", - ".kokoro/continuous/common.cfg", - ".kokoro/continuous/continuous.cfg", - ".kokoro/docker/docs/Dockerfile", - ".kokoro/docker/docs/fetch_gpg_keys.sh", - ".kokoro/docs/common.cfg", - ".kokoro/docs/docs-presubmit.cfg", - ".kokoro/docs/docs.cfg", - ".kokoro/populate-secrets.sh", - ".kokoro/presubmit/common.cfg", - ".kokoro/presubmit/presubmit.cfg", - ".kokoro/publish-docs.sh", - ".kokoro/release.sh", - ".kokoro/release/common.cfg", - ".kokoro/release/release.cfg", - ".kokoro/samples/lint/common.cfg", - ".kokoro/samples/lint/continuous.cfg", - ".kokoro/samples/lint/periodic.cfg", - ".kokoro/samples/lint/presubmit.cfg", - ".kokoro/samples/python3.6/common.cfg", - ".kokoro/samples/python3.6/continuous.cfg", - ".kokoro/samples/python3.6/periodic.cfg", - ".kokoro/samples/python3.6/presubmit.cfg", - ".kokoro/samples/python3.7/common.cfg", - ".kokoro/samples/python3.7/continuous.cfg", - ".kokoro/samples/python3.7/periodic.cfg", - ".kokoro/samples/python3.7/presubmit.cfg", - ".kokoro/samples/python3.8/common.cfg", - ".kokoro/samples/python3.8/continuous.cfg", - ".kokoro/samples/python3.8/periodic.cfg", - ".kokoro/samples/python3.8/presubmit.cfg", - ".kokoro/test-samples.sh", - ".kokoro/trampoline.sh", - ".kokoro/trampoline_v2.sh", - ".pre-commit-config.yaml", - ".trampolinerc", - "CODE_OF_CONDUCT.md", - "CONTRIBUTING.rst", - "LICENSE", - "MANIFEST.in", - "docs/_static/custom.css", - "docs/_templates/layout.html", - "docs/conf.py", - "docs/multiprocessing.rst", - "docs/videointelligence_v1/services.rst", - "docs/videointelligence_v1/types.rst", - "docs/videointelligence_v1beta2/services.rst", - "docs/videointelligence_v1beta2/types.rst", - "docs/videointelligence_v1p1beta1/services.rst", - "docs/videointelligence_v1p1beta1/types.rst", - "docs/videointelligence_v1p2beta1/services.rst", - "docs/videointelligence_v1p2beta1/types.rst", - "docs/videointelligence_v1p3beta1/services.rst", - "docs/videointelligence_v1p3beta1/types.rst", - "google/cloud/videointelligence/__init__.py", - "google/cloud/videointelligence/py.typed", - "google/cloud/videointelligence_v1/__init__.py", - "google/cloud/videointelligence_v1/proto/video_intelligence.proto", - "google/cloud/videointelligence_v1/py.typed", - "google/cloud/videointelligence_v1/services/__init__.py", - "google/cloud/videointelligence_v1/services/video_intelligence_service/__init__.py", - "google/cloud/videointelligence_v1/services/video_intelligence_service/async_client.py", - "google/cloud/videointelligence_v1/services/video_intelligence_service/client.py", - "google/cloud/videointelligence_v1/services/video_intelligence_service/transports/__init__.py", - "google/cloud/videointelligence_v1/services/video_intelligence_service/transports/base.py", - "google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc.py", - "google/cloud/videointelligence_v1/services/video_intelligence_service/transports/grpc_asyncio.py", - "google/cloud/videointelligence_v1/types/__init__.py", - "google/cloud/videointelligence_v1/types/video_intelligence.py", - "google/cloud/videointelligence_v1beta2/__init__.py", - "google/cloud/videointelligence_v1beta2/proto/video_intelligence.proto", - "google/cloud/videointelligence_v1beta2/py.typed", - "google/cloud/videointelligence_v1beta2/services/__init__.py", - "google/cloud/videointelligence_v1beta2/services/video_intelligence_service/__init__.py", - "google/cloud/videointelligence_v1beta2/services/video_intelligence_service/async_client.py", - "google/cloud/videointelligence_v1beta2/services/video_intelligence_service/client.py", - "google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/__init__.py", - "google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/base.py", - "google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc.py", - "google/cloud/videointelligence_v1beta2/services/video_intelligence_service/transports/grpc_asyncio.py", - "google/cloud/videointelligence_v1beta2/types/__init__.py", - "google/cloud/videointelligence_v1beta2/types/video_intelligence.py", - "google/cloud/videointelligence_v1p1beta1/__init__.py", - "google/cloud/videointelligence_v1p1beta1/proto/video_intelligence.proto", - "google/cloud/videointelligence_v1p1beta1/py.typed", - "google/cloud/videointelligence_v1p1beta1/services/__init__.py", - "google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/__init__.py", - "google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/async_client.py", - "google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/client.py", - "google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/__init__.py", - "google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/base.py", - "google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc.py", - "google/cloud/videointelligence_v1p1beta1/services/video_intelligence_service/transports/grpc_asyncio.py", - "google/cloud/videointelligence_v1p1beta1/types/__init__.py", - "google/cloud/videointelligence_v1p1beta1/types/video_intelligence.py", - "google/cloud/videointelligence_v1p2beta1/__init__.py", - "google/cloud/videointelligence_v1p2beta1/proto/video_intelligence.proto", - "google/cloud/videointelligence_v1p2beta1/py.typed", - "google/cloud/videointelligence_v1p2beta1/services/__init__.py", - "google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/__init__.py", - "google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/async_client.py", - "google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/client.py", - "google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/__init__.py", - "google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/base.py", - "google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc.py", - "google/cloud/videointelligence_v1p2beta1/services/video_intelligence_service/transports/grpc_asyncio.py", - "google/cloud/videointelligence_v1p2beta1/types/__init__.py", - "google/cloud/videointelligence_v1p2beta1/types/video_intelligence.py", - "google/cloud/videointelligence_v1p3beta1/__init__.py", - "google/cloud/videointelligence_v1p3beta1/proto/video_intelligence.proto", - "google/cloud/videointelligence_v1p3beta1/py.typed", - "google/cloud/videointelligence_v1p3beta1/services/__init__.py", - "google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/__init__.py", - "google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/async_client.py", - "google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/client.py", - "google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/__init__.py", - "google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/base.py", - "google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc.py", - "google/cloud/videointelligence_v1p3beta1/services/streaming_video_intelligence_service/transports/grpc_asyncio.py", - "google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/__init__.py", - "google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/async_client.py", - "google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/client.py", - "google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/__init__.py", - "google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/base.py", - "google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc.py", - "google/cloud/videointelligence_v1p3beta1/services/video_intelligence_service/transports/grpc_asyncio.py", - "google/cloud/videointelligence_v1p3beta1/types/__init__.py", - "google/cloud/videointelligence_v1p3beta1/types/video_intelligence.py", - "mypy.ini", - "noxfile.py", - "renovate.json", - "samples/AUTHORING_GUIDE.md", - "samples/CONTRIBUTING.md", - "samples/analyze/noxfile.py", - "samples/labels/noxfile.py", - "samples/quickstart/noxfile.py", - "samples/shotchange/noxfile.py", - "scripts/decrypt-secrets.sh", - "scripts/fixup_videointelligence_v1_keywords.py", - "scripts/fixup_videointelligence_v1beta2_keywords.py", - "scripts/fixup_videointelligence_v1p1beta1_keywords.py", - "scripts/fixup_videointelligence_v1p2beta1_keywords.py", - "scripts/fixup_videointelligence_v1p3beta1_keywords.py", - "scripts/readme-gen/readme_gen.py", - "scripts/readme-gen/templates/README.tmpl.rst", - "scripts/readme-gen/templates/auth.tmpl.rst", - "scripts/readme-gen/templates/auth_api_key.tmpl.rst", - "scripts/readme-gen/templates/install_deps.tmpl.rst", - "scripts/readme-gen/templates/install_portaudio.tmpl.rst", - "setup.cfg", - "testing/.gitignore", - "tests/unit/gapic/videointelligence_v1/__init__.py", - "tests/unit/gapic/videointelligence_v1/test_video_intelligence_service.py", - "tests/unit/gapic/videointelligence_v1beta2/__init__.py", - "tests/unit/gapic/videointelligence_v1beta2/test_video_intelligence_service.py", - "tests/unit/gapic/videointelligence_v1p1beta1/__init__.py", - "tests/unit/gapic/videointelligence_v1p1beta1/test_video_intelligence_service.py", - "tests/unit/gapic/videointelligence_v1p2beta1/__init__.py", - "tests/unit/gapic/videointelligence_v1p2beta1/test_video_intelligence_service.py", - "tests/unit/gapic/videointelligence_v1p3beta1/__init__.py", - "tests/unit/gapic/videointelligence_v1p3beta1/test_streaming_video_intelligence_service.py", - "tests/unit/gapic/videointelligence_v1p3beta1/test_video_intelligence_service.py" ] } \ No newline at end of file diff --git a/packages/google-cloud-videointelligence/testing/constraints-3.10.txt b/packages/google-cloud-videointelligence/testing/constraints-3.10.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-videointelligence/testing/constraints-3.11.txt b/packages/google-cloud-videointelligence/testing/constraints-3.11.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-videointelligence/testing/constraints-3.6.txt b/packages/google-cloud-videointelligence/testing/constraints-3.6.txt new file mode 100644 index 000000000000..88b0c2fec5fb --- /dev/null +++ b/packages/google-cloud-videointelligence/testing/constraints-3.6.txt @@ -0,0 +1,10 @@ +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List *all* library dependencies and extras in this file. +# Pin the version to the lower bound. +# +# e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev", +# Then this file should have foo==1.14.0 +google-api-core==1.22.2 +proto-plus==1.10.0 +libcst==0.2.5 diff --git a/packages/google-cloud-videointelligence/testing/constraints-3.7.txt b/packages/google-cloud-videointelligence/testing/constraints-3.7.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-videointelligence/testing/constraints-3.8.txt b/packages/google-cloud-videointelligence/testing/constraints-3.8.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-videointelligence/testing/constraints-3.9.txt b/packages/google-cloud-videointelligence/testing/constraints-3.9.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1/__init__.py b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1/__init__.py index 8b137891791f..42ffdf2bc43d 100644 --- a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1/__init__.py +++ b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1/__init__.py @@ -1 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1/test_video_intelligence_service.py b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1/test_video_intelligence_service.py index 51bf7da6e4fe..9e973d585ec9 100644 --- a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1/test_video_intelligence_service.py +++ b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1/test_video_intelligence_service.py @@ -97,7 +97,25 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( "client_class", - [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient], + [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], +) +def test_video_intelligence_service_client_from_service_account_info(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "videointelligence.googleapis.com:443" + + +@pytest.mark.parametrize( + "client_class", + [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_file(client_class): creds = credentials.AnonymousCredentials() @@ -107,16 +125,21 @@ def test_video_intelligence_service_client_from_service_account_file(client_clas factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "videointelligence.googleapis.com:443" def test_video_intelligence_service_client_get_transport_class(): transport = VideoIntelligenceServiceClient.get_transport_class() - assert transport == transports.VideoIntelligenceServiceGrpcTransport + available_transports = [ + transports.VideoIntelligenceServiceGrpcTransport, + ] + assert transport in available_transports transport = VideoIntelligenceServiceClient.get_transport_class("grpc") assert transport == transports.VideoIntelligenceServiceGrpcTransport @@ -175,7 +198,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -191,7 +214,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -207,7 +230,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -235,7 +258,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -296,29 +319,25 @@ def test_video_intelligence_service_client_mtls_env_auto( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() - with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds - ): - patched.return_value = None - client = client_class(client_options=options) + patched.return_value = None + client = client_class(client_options=options) - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) # Check the case ADC client cert is provided. Whether client cert is used depends on # GOOGLE_API_USE_CLIENT_CERTIFICATE value. @@ -327,66 +346,53 @@ def test_video_intelligence_service_client_mtls_env_auto( ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False patched.return_value = None client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_ENDPOINT, + host=expected_host, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=expected_client_cert_source, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + @pytest.mark.parametrize( "client_class,transport_class,transport_name", @@ -416,7 +422,7 @@ def test_video_intelligence_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -450,7 +456,7 @@ def test_video_intelligence_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -469,7 +475,7 @@ def test_video_intelligence_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -507,6 +513,22 @@ def test_annotate_video_from_dict(): test_annotate_video(request_type=dict) +def test_annotate_video_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = VideoIntelligenceServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: + client.annotate_video() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == video_intelligence.AnnotateVideoRequest() + + @pytest.mark.asyncio async def test_annotate_video_async( transport: str = "grpc_asyncio", @@ -799,6 +821,53 @@ def test_video_intelligence_service_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( + transport_class, +): + cred = credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + def test_video_intelligence_service_host_no_port(): client = VideoIntelligenceServiceClient( credentials=credentials.AnonymousCredentials(), @@ -820,7 +889,7 @@ def test_video_intelligence_service_host_with_port(): def test_video_intelligence_service_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.VideoIntelligenceServiceGrpcTransport( @@ -832,7 +901,7 @@ def test_video_intelligence_service_grpc_transport_channel(): def test_video_intelligence_service_grpc_asyncio_transport_channel(): - channel = aio.insecure_channel("http://localhost/") + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.VideoIntelligenceServiceGrpcAsyncIOTransport( @@ -843,6 +912,8 @@ def test_video_intelligence_service_grpc_asyncio_transport_channel(): assert transport._ssl_channel_credentials == None +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -857,7 +928,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour "grpc.ssl_channel_credentials", autospec=True ) as grpc_ssl_channel_cred: with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_ssl_cred = mock.Mock() grpc_ssl_channel_cred.return_value = mock_ssl_cred @@ -895,6 +966,8 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour assert transport._ssl_channel_credentials == mock_ssl_cred +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -910,7 +983,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_adc(transport_cl ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel diff --git a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1beta2/__init__.py b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1beta2/__init__.py index 8b137891791f..42ffdf2bc43d 100644 --- a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1beta2/__init__.py +++ b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1beta2/__init__.py @@ -1 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1beta2/test_video_intelligence_service.py b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1beta2/test_video_intelligence_service.py index df196968921d..684d8d20ce86 100644 --- a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1beta2/test_video_intelligence_service.py +++ b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1beta2/test_video_intelligence_service.py @@ -97,7 +97,25 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( "client_class", - [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient], + [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], +) +def test_video_intelligence_service_client_from_service_account_info(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "videointelligence.googleapis.com:443" + + +@pytest.mark.parametrize( + "client_class", + [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_file(client_class): creds = credentials.AnonymousCredentials() @@ -107,16 +125,21 @@ def test_video_intelligence_service_client_from_service_account_file(client_clas factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "videointelligence.googleapis.com:443" def test_video_intelligence_service_client_get_transport_class(): transport = VideoIntelligenceServiceClient.get_transport_class() - assert transport == transports.VideoIntelligenceServiceGrpcTransport + available_transports = [ + transports.VideoIntelligenceServiceGrpcTransport, + ] + assert transport in available_transports transport = VideoIntelligenceServiceClient.get_transport_class("grpc") assert transport == transports.VideoIntelligenceServiceGrpcTransport @@ -175,7 +198,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -191,7 +214,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -207,7 +230,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -235,7 +258,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -296,29 +319,25 @@ def test_video_intelligence_service_client_mtls_env_auto( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() - with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds - ): - patched.return_value = None - client = client_class(client_options=options) + patched.return_value = None + client = client_class(client_options=options) - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) # Check the case ADC client cert is provided. Whether client cert is used depends on # GOOGLE_API_USE_CLIENT_CERTIFICATE value. @@ -327,66 +346,53 @@ def test_video_intelligence_service_client_mtls_env_auto( ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False patched.return_value = None client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_ENDPOINT, + host=expected_host, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=expected_client_cert_source, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + @pytest.mark.parametrize( "client_class,transport_class,transport_name", @@ -416,7 +422,7 @@ def test_video_intelligence_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -450,7 +456,7 @@ def test_video_intelligence_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -469,7 +475,7 @@ def test_video_intelligence_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -507,6 +513,22 @@ def test_annotate_video_from_dict(): test_annotate_video(request_type=dict) +def test_annotate_video_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = VideoIntelligenceServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: + client.annotate_video() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == video_intelligence.AnnotateVideoRequest() + + @pytest.mark.asyncio async def test_annotate_video_async( transport: str = "grpc_asyncio", @@ -799,6 +821,53 @@ def test_video_intelligence_service_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( + transport_class, +): + cred = credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + def test_video_intelligence_service_host_no_port(): client = VideoIntelligenceServiceClient( credentials=credentials.AnonymousCredentials(), @@ -820,7 +889,7 @@ def test_video_intelligence_service_host_with_port(): def test_video_intelligence_service_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.VideoIntelligenceServiceGrpcTransport( @@ -832,7 +901,7 @@ def test_video_intelligence_service_grpc_transport_channel(): def test_video_intelligence_service_grpc_asyncio_transport_channel(): - channel = aio.insecure_channel("http://localhost/") + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.VideoIntelligenceServiceGrpcAsyncIOTransport( @@ -843,6 +912,8 @@ def test_video_intelligence_service_grpc_asyncio_transport_channel(): assert transport._ssl_channel_credentials == None +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -857,7 +928,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour "grpc.ssl_channel_credentials", autospec=True ) as grpc_ssl_channel_cred: with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_ssl_cred = mock.Mock() grpc_ssl_channel_cred.return_value = mock_ssl_cred @@ -895,6 +966,8 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour assert transport._ssl_channel_credentials == mock_ssl_cred +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -910,7 +983,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_adc(transport_cl ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel diff --git a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p1beta1/__init__.py b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p1beta1/__init__.py index 8b137891791f..42ffdf2bc43d 100644 --- a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p1beta1/__init__.py +++ b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p1beta1/__init__.py @@ -1 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p1beta1/test_video_intelligence_service.py b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p1beta1/test_video_intelligence_service.py index d68bacabe713..a631e0e75285 100644 --- a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p1beta1/test_video_intelligence_service.py +++ b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p1beta1/test_video_intelligence_service.py @@ -97,7 +97,25 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( "client_class", - [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient], + [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], +) +def test_video_intelligence_service_client_from_service_account_info(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "videointelligence.googleapis.com:443" + + +@pytest.mark.parametrize( + "client_class", + [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_file(client_class): creds = credentials.AnonymousCredentials() @@ -107,16 +125,21 @@ def test_video_intelligence_service_client_from_service_account_file(client_clas factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "videointelligence.googleapis.com:443" def test_video_intelligence_service_client_get_transport_class(): transport = VideoIntelligenceServiceClient.get_transport_class() - assert transport == transports.VideoIntelligenceServiceGrpcTransport + available_transports = [ + transports.VideoIntelligenceServiceGrpcTransport, + ] + assert transport in available_transports transport = VideoIntelligenceServiceClient.get_transport_class("grpc") assert transport == transports.VideoIntelligenceServiceGrpcTransport @@ -175,7 +198,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -191,7 +214,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -207,7 +230,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -235,7 +258,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -296,29 +319,25 @@ def test_video_intelligence_service_client_mtls_env_auto( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() - with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds - ): - patched.return_value = None - client = client_class(client_options=options) + patched.return_value = None + client = client_class(client_options=options) - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) # Check the case ADC client cert is provided. Whether client cert is used depends on # GOOGLE_API_USE_CLIENT_CERTIFICATE value. @@ -327,66 +346,53 @@ def test_video_intelligence_service_client_mtls_env_auto( ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False patched.return_value = None client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_ENDPOINT, + host=expected_host, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=expected_client_cert_source, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + @pytest.mark.parametrize( "client_class,transport_class,transport_name", @@ -416,7 +422,7 @@ def test_video_intelligence_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -450,7 +456,7 @@ def test_video_intelligence_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -469,7 +475,7 @@ def test_video_intelligence_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -507,6 +513,22 @@ def test_annotate_video_from_dict(): test_annotate_video(request_type=dict) +def test_annotate_video_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = VideoIntelligenceServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: + client.annotate_video() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == video_intelligence.AnnotateVideoRequest() + + @pytest.mark.asyncio async def test_annotate_video_async( transport: str = "grpc_asyncio", @@ -799,6 +821,53 @@ def test_video_intelligence_service_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( + transport_class, +): + cred = credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + def test_video_intelligence_service_host_no_port(): client = VideoIntelligenceServiceClient( credentials=credentials.AnonymousCredentials(), @@ -820,7 +889,7 @@ def test_video_intelligence_service_host_with_port(): def test_video_intelligence_service_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.VideoIntelligenceServiceGrpcTransport( @@ -832,7 +901,7 @@ def test_video_intelligence_service_grpc_transport_channel(): def test_video_intelligence_service_grpc_asyncio_transport_channel(): - channel = aio.insecure_channel("http://localhost/") + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.VideoIntelligenceServiceGrpcAsyncIOTransport( @@ -843,6 +912,8 @@ def test_video_intelligence_service_grpc_asyncio_transport_channel(): assert transport._ssl_channel_credentials == None +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -857,7 +928,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour "grpc.ssl_channel_credentials", autospec=True ) as grpc_ssl_channel_cred: with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_ssl_cred = mock.Mock() grpc_ssl_channel_cred.return_value = mock_ssl_cred @@ -895,6 +966,8 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour assert transport._ssl_channel_credentials == mock_ssl_cred +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -910,7 +983,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_adc(transport_cl ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel diff --git a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p2beta1/__init__.py b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p2beta1/__init__.py index 8b137891791f..42ffdf2bc43d 100644 --- a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p2beta1/__init__.py +++ b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p2beta1/__init__.py @@ -1 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p2beta1/test_video_intelligence_service.py b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p2beta1/test_video_intelligence_service.py index 8c002be3553c..62cccf878f89 100644 --- a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p2beta1/test_video_intelligence_service.py +++ b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p2beta1/test_video_intelligence_service.py @@ -97,7 +97,25 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( "client_class", - [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient], + [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], +) +def test_video_intelligence_service_client_from_service_account_info(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "videointelligence.googleapis.com:443" + + +@pytest.mark.parametrize( + "client_class", + [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_file(client_class): creds = credentials.AnonymousCredentials() @@ -107,16 +125,21 @@ def test_video_intelligence_service_client_from_service_account_file(client_clas factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "videointelligence.googleapis.com:443" def test_video_intelligence_service_client_get_transport_class(): transport = VideoIntelligenceServiceClient.get_transport_class() - assert transport == transports.VideoIntelligenceServiceGrpcTransport + available_transports = [ + transports.VideoIntelligenceServiceGrpcTransport, + ] + assert transport in available_transports transport = VideoIntelligenceServiceClient.get_transport_class("grpc") assert transport == transports.VideoIntelligenceServiceGrpcTransport @@ -175,7 +198,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -191,7 +214,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -207,7 +230,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -235,7 +258,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -296,29 +319,25 @@ def test_video_intelligence_service_client_mtls_env_auto( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() - with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds - ): - patched.return_value = None - client = client_class(client_options=options) + patched.return_value = None + client = client_class(client_options=options) - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) # Check the case ADC client cert is provided. Whether client cert is used depends on # GOOGLE_API_USE_CLIENT_CERTIFICATE value. @@ -327,66 +346,53 @@ def test_video_intelligence_service_client_mtls_env_auto( ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False patched.return_value = None client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_ENDPOINT, + host=expected_host, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=expected_client_cert_source, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + @pytest.mark.parametrize( "client_class,transport_class,transport_name", @@ -416,7 +422,7 @@ def test_video_intelligence_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -450,7 +456,7 @@ def test_video_intelligence_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -469,7 +475,7 @@ def test_video_intelligence_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -507,6 +513,22 @@ def test_annotate_video_from_dict(): test_annotate_video(request_type=dict) +def test_annotate_video_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = VideoIntelligenceServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: + client.annotate_video() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == video_intelligence.AnnotateVideoRequest() + + @pytest.mark.asyncio async def test_annotate_video_async( transport: str = "grpc_asyncio", @@ -799,6 +821,53 @@ def test_video_intelligence_service_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( + transport_class, +): + cred = credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + def test_video_intelligence_service_host_no_port(): client = VideoIntelligenceServiceClient( credentials=credentials.AnonymousCredentials(), @@ -820,7 +889,7 @@ def test_video_intelligence_service_host_with_port(): def test_video_intelligence_service_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.VideoIntelligenceServiceGrpcTransport( @@ -832,7 +901,7 @@ def test_video_intelligence_service_grpc_transport_channel(): def test_video_intelligence_service_grpc_asyncio_transport_channel(): - channel = aio.insecure_channel("http://localhost/") + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.VideoIntelligenceServiceGrpcAsyncIOTransport( @@ -843,6 +912,8 @@ def test_video_intelligence_service_grpc_asyncio_transport_channel(): assert transport._ssl_channel_credentials == None +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -857,7 +928,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour "grpc.ssl_channel_credentials", autospec=True ) as grpc_ssl_channel_cred: with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_ssl_cred = mock.Mock() grpc_ssl_channel_cred.return_value = mock_ssl_cred @@ -895,6 +966,8 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour assert transport._ssl_channel_credentials == mock_ssl_cred +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -910,7 +983,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_adc(transport_cl ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel diff --git a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p3beta1/__init__.py b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p3beta1/__init__.py index 8b137891791f..42ffdf2bc43d 100644 --- a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p3beta1/__init__.py +++ b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p3beta1/__init__.py @@ -1 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p3beta1/test_streaming_video_intelligence_service.py b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p3beta1/test_streaming_video_intelligence_service.py index e3a41e87d98e..1a3a8551104b 100644 --- a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p3beta1/test_streaming_video_intelligence_service.py +++ b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p3beta1/test_streaming_video_intelligence_service.py @@ -101,6 +101,29 @@ def test__get_default_mtls_endpoint(): ) +@pytest.mark.parametrize( + "client_class", + [ + StreamingVideoIntelligenceServiceClient, + StreamingVideoIntelligenceServiceAsyncClient, + ], +) +def test_streaming_video_intelligence_service_client_from_service_account_info( + client_class, +): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "videointelligence.googleapis.com:443" + + @pytest.mark.parametrize( "client_class", [ @@ -118,16 +141,21 @@ def test_streaming_video_intelligence_service_client_from_service_account_file( factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "videointelligence.googleapis.com:443" def test_streaming_video_intelligence_service_client_get_transport_class(): transport = StreamingVideoIntelligenceServiceClient.get_transport_class() - assert transport == transports.StreamingVideoIntelligenceServiceGrpcTransport + available_transports = [ + transports.StreamingVideoIntelligenceServiceGrpcTransport, + ] + assert transport in available_transports transport = StreamingVideoIntelligenceServiceClient.get_transport_class("grpc") assert transport == transports.StreamingVideoIntelligenceServiceGrpcTransport @@ -186,7 +214,7 @@ def test_streaming_video_intelligence_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -202,7 +230,7 @@ def test_streaming_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -218,7 +246,7 @@ def test_streaming_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -246,7 +274,7 @@ def test_streaming_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -307,29 +335,25 @@ def test_streaming_video_intelligence_service_client_mtls_env_auto( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() - with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds - ): - patched.return_value = None - client = client_class(client_options=options) + patched.return_value = None + client = client_class(client_options=options) - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) # Check the case ADC client cert is provided. Whether client cert is used depends on # GOOGLE_API_USE_CLIENT_CERTIFICATE value. @@ -338,66 +362,53 @@ def test_streaming_video_intelligence_service_client_mtls_env_auto( ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False patched.return_value = None client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_ENDPOINT, + host=expected_host, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=expected_client_cert_source, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + @pytest.mark.parametrize( "client_class,transport_class,transport_name", @@ -427,7 +438,7 @@ def test_streaming_video_intelligence_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -461,7 +472,7 @@ def test_streaming_video_intelligence_service_client_client_options_credentials_ credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -480,7 +491,7 @@ def test_streaming_video_intelligence_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -728,6 +739,53 @@ def test_streaming_video_intelligence_service_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class", + [ + transports.StreamingVideoIntelligenceServiceGrpcTransport, + transports.StreamingVideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +def test_streaming_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( + transport_class, +): + cred = credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + def test_streaming_video_intelligence_service_host_no_port(): client = StreamingVideoIntelligenceServiceClient( credentials=credentials.AnonymousCredentials(), @@ -749,7 +807,7 @@ def test_streaming_video_intelligence_service_host_with_port(): def test_streaming_video_intelligence_service_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.StreamingVideoIntelligenceServiceGrpcTransport( @@ -761,7 +819,7 @@ def test_streaming_video_intelligence_service_grpc_transport_channel(): def test_streaming_video_intelligence_service_grpc_asyncio_transport_channel(): - channel = aio.insecure_channel("http://localhost/") + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.StreamingVideoIntelligenceServiceGrpcAsyncIOTransport( @@ -772,6 +830,8 @@ def test_streaming_video_intelligence_service_grpc_asyncio_transport_channel(): assert transport._ssl_channel_credentials == None +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -786,7 +846,7 @@ def test_streaming_video_intelligence_service_transport_channel_mtls_with_client "grpc.ssl_channel_credentials", autospec=True ) as grpc_ssl_channel_cred: with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_ssl_cred = mock.Mock() grpc_ssl_channel_cred.return_value = mock_ssl_cred @@ -824,6 +884,8 @@ def test_streaming_video_intelligence_service_transport_channel_mtls_with_client assert transport._ssl_channel_credentials == mock_ssl_cred +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -841,7 +903,7 @@ def test_streaming_video_intelligence_service_transport_channel_mtls_with_adc( ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel diff --git a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p3beta1/test_video_intelligence_service.py b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p3beta1/test_video_intelligence_service.py index 7c66065376f4..45ccb0aee4bd 100644 --- a/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p3beta1/test_video_intelligence_service.py +++ b/packages/google-cloud-videointelligence/tests/unit/gapic/videointelligence_v1p3beta1/test_video_intelligence_service.py @@ -97,7 +97,25 @@ def test__get_default_mtls_endpoint(): @pytest.mark.parametrize( "client_class", - [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient], + [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], +) +def test_video_intelligence_service_client_from_service_account_info(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == "videointelligence.googleapis.com:443" + + +@pytest.mark.parametrize( + "client_class", + [VideoIntelligenceServiceClient, VideoIntelligenceServiceAsyncClient,], ) def test_video_intelligence_service_client_from_service_account_file(client_class): creds = credentials.AnonymousCredentials() @@ -107,16 +125,21 @@ def test_video_intelligence_service_client_from_service_account_file(client_clas factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "videointelligence.googleapis.com:443" def test_video_intelligence_service_client_get_transport_class(): transport = VideoIntelligenceServiceClient.get_transport_class() - assert transport == transports.VideoIntelligenceServiceGrpcTransport + available_transports = [ + transports.VideoIntelligenceServiceGrpcTransport, + ] + assert transport in available_transports transport = VideoIntelligenceServiceClient.get_transport_class("grpc") assert transport == transports.VideoIntelligenceServiceGrpcTransport @@ -175,7 +198,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -191,7 +214,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -207,7 +230,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_MTLS_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -235,7 +258,7 @@ def test_video_intelligence_service_client_client_options( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -296,29 +319,25 @@ def test_video_intelligence_service_client_mtls_env_auto( client_cert_source=client_cert_source_callback ) with mock.patch.object(transport_class, "__init__") as patched: - ssl_channel_creds = mock.Mock() - with mock.patch( - "grpc.ssl_channel_credentials", return_value=ssl_channel_creds - ): - patched.return_value = None - client = client_class(client_options=options) + patched.return_value = None + client = client_class(client_options=options) - if use_client_cert_env == "false": - expected_ssl_channel_creds = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_ssl_channel_creds = ssl_channel_creds - expected_host = client.DEFAULT_MTLS_ENDPOINT + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client.DEFAULT_ENDPOINT + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) # Check the case ADC client cert is provided. Whether client cert is used depends on # GOOGLE_API_USE_CLIENT_CERTIFICATE value. @@ -327,66 +346,53 @@ def test_video_intelligence_service_client_mtls_env_auto( ): with mock.patch.object(transport_class, "__init__") as patched: with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, ): with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.ssl_credentials", - new_callable=mock.PropertyMock, - ) as ssl_credentials_mock: - if use_client_cert_env == "false": - is_mtls_mock.return_value = False - ssl_credentials_mock.return_value = None - expected_host = client.DEFAULT_ENDPOINT - expected_ssl_channel_creds = None - else: - is_mtls_mock.return_value = True - ssl_credentials_mock.return_value = mock.Mock() - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_ssl_channel_creds = ( - ssl_credentials_mock.return_value - ) - - patched.return_value = None - client = client_class() - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - ssl_channel_credentials=expected_ssl_channel_creds, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - ) + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client.DEFAULT_ENDPOINT + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.grpc.SslCredentials.__init__", return_value=None - ): - with mock.patch( - "google.auth.transport.grpc.SslCredentials.is_mtls", - new_callable=mock.PropertyMock, - ) as is_mtls_mock: - is_mtls_mock.return_value = False patched.return_value = None client = client_class() patched.assert_called_once_with( credentials=None, credentials_file=None, - host=client.DEFAULT_ENDPOINT, + host=expected_host, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=expected_client_cert_source, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + ) + @pytest.mark.parametrize( "client_class,transport_class,transport_name", @@ -416,7 +422,7 @@ def test_video_intelligence_service_client_client_options_scopes( credentials_file=None, host=client.DEFAULT_ENDPOINT, scopes=["1", "2"], - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -450,7 +456,7 @@ def test_video_intelligence_service_client_client_options_credentials_file( credentials_file="credentials.json", host=client.DEFAULT_ENDPOINT, scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -469,7 +475,7 @@ def test_video_intelligence_service_client_client_options_from_dict(): credentials_file=None, host="squid.clam.whelk", scopes=None, - ssl_channel_credentials=None, + client_cert_source_for_mtls=None, quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, ) @@ -507,6 +513,22 @@ def test_annotate_video_from_dict(): test_annotate_video(request_type=dict) +def test_annotate_video_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = VideoIntelligenceServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.annotate_video), "__call__") as call: + client.annotate_video() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == video_intelligence.AnnotateVideoRequest() + + @pytest.mark.asyncio async def test_annotate_video_async( transport: str = "grpc_asyncio", @@ -799,6 +821,53 @@ def test_video_intelligence_service_transport_auth_adc(): ) +@pytest.mark.parametrize( + "transport_class", + [ + transports.VideoIntelligenceServiceGrpcTransport, + transports.VideoIntelligenceServiceGrpcAsyncIOTransport, + ], +) +def test_video_intelligence_service_grpc_transport_client_cert_source_for_mtls( + transport_class, +): + cred = credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + def test_video_intelligence_service_host_no_port(): client = VideoIntelligenceServiceClient( credentials=credentials.AnonymousCredentials(), @@ -820,7 +889,7 @@ def test_video_intelligence_service_host_with_port(): def test_video_intelligence_service_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.VideoIntelligenceServiceGrpcTransport( @@ -832,7 +901,7 @@ def test_video_intelligence_service_grpc_transport_channel(): def test_video_intelligence_service_grpc_asyncio_transport_channel(): - channel = aio.insecure_channel("http://localhost/") + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) # Check that channel is used if provided. transport = transports.VideoIntelligenceServiceGrpcAsyncIOTransport( @@ -843,6 +912,8 @@ def test_video_intelligence_service_grpc_asyncio_transport_channel(): assert transport._ssl_channel_credentials == None +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -857,7 +928,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour "grpc.ssl_channel_credentials", autospec=True ) as grpc_ssl_channel_cred: with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_ssl_cred = mock.Mock() grpc_ssl_channel_cred.return_value = mock_ssl_cred @@ -895,6 +966,8 @@ def test_video_intelligence_service_transport_channel_mtls_with_client_cert_sour assert transport._ssl_channel_credentials == mock_ssl_cred +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. @pytest.mark.parametrize( "transport_class", [ @@ -910,7 +983,7 @@ def test_video_intelligence_service_transport_channel_mtls_with_adc(transport_cl ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), ): with mock.patch.object( - transport_class, "create_channel", autospec=True + transport_class, "create_channel" ) as grpc_create_channel: mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel